啪啪打脸!领导说:try-catch要放在循环体外!(上)

简介: 啪啪打脸!领导说:try-catch要放在循环体外!

哈喽,亲爱的小伙伴们,技术学磊哥,进步没得说!欢迎来到新一期的性能解读系列,我是磊哥。


今天给大家带来的是关于 try-catch 应该放在循环体外,还是放在循环体内的文章,我们将从性能业务场景分析这两个方面来回答此问题。


很多人对 try-catch 有一定的误解,比如我们经常会把它(try-catch)和“低性能”直接画上等号,但对 try-catch 的本质(是什么)却缺少着最基础的了解,因此我们也会在本篇中对 try-catch 的本质进行相关的探索


image.png


小贴士:我会尽量用代码和评测结果来证明问题,但由于本身认知的局限,如有不当之处,请读者朋友们在评论区指出。


性能评测


话不多说,我们直接来开始今天的测试,本文我们依旧使用 Oracle 官方提供的 JMH(Java Microbenchmark Harness,JAVA 微基准测试套件)来进行测试。


首先在 pom.xml 文件中添加 JMH 框架,配置如下:


<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core -->
<dependency>
   <groupId>org.openjdk.jmh</groupId>
   <artifactId>jmh-core</artifactId>
   <version>{version}</version>
</dependency>


完整测试代码如下:


import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
/**
 * try - catch 性能测试
 */
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 1, time = 1, timeUnit = TimeUnit.SECONDS) // 预热 1 轮,每次 1s
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试 5 轮,每次 3s
@Fork(1) // fork 1 个线程
@State(Scope.Benchmark)
@Threads(100)
public class TryCatchPerformanceTest {
    private static final int forSize = 1000; // 循环次数
    public static void main(String[] args) throws RunnerException {
        // 启动基准测试
        Options opt = new OptionsBuilder()
                .include(TryCatchPerformanceTest.class.getSimpleName()) // 要导入的测试类
                .build();
        new Runner(opt).run(); // 执行测试
    }
    @Benchmark
    public int innerForeach() {
        int count = 0;
        for (int i = 0; i < forSize; i++) {
            try {
                if (i == forSize) {
                    throw new Exception("new Exception");
                }
                count++;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return count;
    }
    @Benchmark
    public int outerForeach() {
        int count = 0;
        try {
            for (int i = 0; i < forSize; i++) {
                if (i == forSize) {
                    throw new Exception("new Exception");
                }
                count++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return count;
    }
}


以上代码的测试结果为:


image.png


从以上结果可以看出,程序在循环 1000 次的情况下,单次平均执行时间为:


  • 循环内包含 try-catch 的平均执行时间是 635 纳秒 ±75 纳秒,也就是 635 纳秒上下误差是 75 纳秒;
  • 循环外包含 try-catch 的平均执行时间是 630 纳秒,上下误差 38 纳秒。


也就是说,在没有发生异常的情况下,除去误差值,我们得到的结论是:try-catch 无论是在 for 循环内还是  for 循环外,它们的性能相同,几乎没有任何差别


image.png



相关文章
|
3月前
|
搜索推荐 大数据 数据处理
面试官:try-catch 到底写在循环里面好,还是外面好?大部分人都会答错!
面试官:try-catch 到底写在循环里面好,还是外面好?大部分人都会答错!
45 0
|
缓存 前端开发 Java
支付宝二面:使用 try-catch 捕获异常会影响性能吗?大部分人都会答错!
支付宝二面:使用 try-catch 捕获异常会影响性能吗?大部分人都会答错!
154 0
支付宝二面:使用 try-catch 捕获异常会影响性能吗?大部分人都会答错!
|
前端开发 Java Spring
求求你不要写满屏的 try...catch 了,这才是优雅的处理方式,真香...
求求你不要写满屏的 try...catch 了,这才是优雅的处理方式,真香...
267 0
求求你不要写满屏的 try...catch 了,这才是优雅的处理方式,真香...
try catch 应该放在for里还是不该放for里
try catch 应该放在for里还是不该放for里
108 0
|
存储 Oracle Java
try-catch-finally中的4个巨坑,老程序员也搞不定!
在 Java 语言中 try-catch-finally 看似简单,一副人畜无害的样子,但想要真正的“掌控”它,却并不是一件容易的事。别的不说,咱就拿 fianlly 来说吧,别看它的功能单一,但使用起来却“暗藏杀机”,若您不信,咱来看下面的这几个例子...
199 0
try-catch-finally中的4个巨坑,老程序员也搞不定!
|
Python
又烧脑又炫技还没什么用,在代码里面打印自身
又烧脑又炫技还没什么用,在代码里面打印自身
204 0
又烧脑又炫技还没什么用,在代码里面打印自身
|
存储 安全 关系型数据库
完蛋,公司被一条 update 语句干趴了!
不要小看一条 update 语句,在生产机上使用不当可能会导致业务停滞,甚至崩溃。 当我们要执行 update 语句的时候,确保 where 条件中带上了索引列,并且在测试机确认该语句是否走的是索引扫描,防止因为扫描全表,而对表中的所有记录加上锁。 我们可以打开 MySQL 里的 sql_safe_updates 参数,这样可以预防 update 操作时 where 条件没有带上索引列。 如果发现即使在 where 条件中带上了列索引列,优化器走的还是全标扫描,这时我们就要使用 force index([index_name]) 可以告诉优化器使用哪个索引。
完蛋,公司被一条 update 语句干趴了!
啪啪打脸!领导说:try-catch要放在循环体外!(下)
啪啪打脸!领导说:try-catch要放在循环体外!
182 0
啪啪打脸!领导说:try-catch要放在循环体外!(下)
|
程序员
try-catch-finally中的4个巨坑,老程序员也搞不定!(2)
try-catch-finally中的4个巨坑,老程序员也搞不定!(2)
136 0
try-catch-finally中的4个巨坑,老程序员也搞不定!(2)