美文网首页
使用 try-catch 捕获异常会影响性能吗?

使用 try-catch 捕获异常会影响性能吗?

作者: flyjar | 来源:发表于2023-03-03 09:20 被阅读0次
    for (int i = 0; i < 5000; i++) {
         try {
             dosth
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
    

    此段代码的目的明显是让循环内部单次调用出错不影响循环的运行。但是如果将try放到for的外部,就改变了业务逻辑。导致一直dosth失败,整个循环都会结束。

    那么try-catch到底会不会影响性能呢?我们来测试一下

    public class TryCatchTest {
    
        @Benchmark
        public void tryfor(Blackhole blackhole) {
            try {
                for (int i = 0; i < 5000; i++) {
                    blackhole.consume(i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Benchmark
        public void fortry(Blackhole blackhole) {
            for (int i = 0; i < 5000; i++) {
                try {
                    blackhole.consume(i);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    

    我们来用 benchmark,跑一下的结果如下:


    image.png

    可以看到,两者的性能(数字越大越好)其实差不多:

    • fortry: 86,261(100359-14098) ~ 114,457(100359+14098)
    • tryfor: 95,961(103216-7255) ~ 110,471(103216+7255)
      我再调小(一般业务场景 for 循环次数都不会很多)下 for 循环的次数为 1000 ,结果也是差不多:


      image.png

    我们发现二者的差异竟然没有多大,那网上说的try-catch会影响性能是怎么回事呢

    来看一下字节码

    try for 的字节码

    异常表记录的是 0 - 20 行,如果这些行里面的代码出现问题,直接跳到 23 行处理。


    image.png

    for try 的字节码

    差别也就是异常表的范围小点,包的是 9-14 行,其它跟 tryfor 都差不多。

    image.png

    所以从字节码层面来看,没抛错两者的执行效率其实没啥差别。

    “那为什么网上流传着try-catch会有性能问题的说法啊?”老陈觉得非常奇怪。

    这个说法确实有,在《Effective Java》这本书里就提到了 try-catch 性能问题:


    image.png

    并且还有下面一段话:


    image.png
    正所谓听话不能听一半,以前读书时候最怕的就是一知半解,因为完全理解选择题能选对,完全不懂蒙可能蒙对,一知半解必定选到错误的选项!

    《Effective Java》书中说的其实是不要用 try-catch 来代替正常的代码,书中的举例了正常的 for 循环肯定这样实现:


    image.png

    但有个卧龙偏偏不这样实现,要通过 try-catch 拐着弯来实现循环:


    image.png
    这操作我只能说有点逆天,这两个实现的对比就有性能损耗了。

    我们直接再跑下有try-catch 的代码和没 try-catch的 for 循环区别,代码如下:


    image.png

    结果如下:


    image.png

    +-差不多,直接看前面的分数对比,没有 ry-catch 的性能确实好些,这也和书中说的 try-catch 会影响 JVM 一些特定的优化说法吻合,但是具体没有说影响哪些优化,我猜测可能是指令重排之类的。

    最后,总结下有关 try-catch 性能问题说法:

    try-catch 相比较没 try-catch,确实有一定的性能影响,但是旨在不推荐我们用 try-catch 来代替正常能不用 try-catch 的实现,而不是不让用 try-catch。
    for循环内用 try-catch 和用 try-catch 包裹整个 for 循环性能差不多,但是其实两者本质上是业务处理方式的不同,跟性能扯不上关系,关键看你的业务流程处理。
    虽然知道try-catch会有性能影响,但是业务上不需要避讳其使用,业务实现优先(只要不是书中举例的那种逆天代码就行),非特殊情况下性能都是其次,有意识地避免大范围的try-catch,只 catch 需要的部分即可(没把握全 catch 也行,代码安全执行第一)。

    相关文章

      网友评论

          本文标题:使用 try-catch 捕获异常会影响性能吗?

          本文链接:https://www.haomeiwen.com/subject/rjmsldtx.html