Redian新闻
>
扯什么 try-catch 性能问题?

扯什么 try-catch 性能问题?

科技

“yes,你看着这鬼代码,竟然在 for 循环里面搞了个 try-catch,不知道try-catch有性能损耗吗?”老陈煞有其事地指着屏幕里的代码:

 for (int i = 0; i < 5000; i++) {
     try {
         dosth
     } catch (Exception e) {
         e.printStackTrace();
     }
 }

我探过头去看了眼代码,“那老陈你觉得该怎么改?”

“当然是把 try-catch 提到外面啊!”老陈脑子都不转一下,脱口而出。

“你是不是傻?且不说性能,这代码的目的明显是让循环内部单次调用出错不影响循环的运行,你其到外面业务逻辑不就变了吗!”

老陈挠了挠他的地中海,“好像也是啊!”

“回过头来,catch 整个 for 循环和在循环内部  catch,在不出错的情况下,其实性能差不多。” 我喝一口咖啡不经意地提到,准备在老陈前面秀一下。

“啥意思?”老陈有点懵地看着我,“try-catch是有性能损耗的,我可是看过网上资料的!”

果然,老陈上钩了,我二话不说直接打开 idea,一顿操作敲了以下代码:

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();
            }
        }
    }

}

“BB 不如 show code,看到没,老陈,我把 try-catch 从 for 循环里面提出来跟在for循环里面做个对比跑一下,你猜猜两个差多少?”

“切,肯定 tryfor 性能好,想都不用想,不是的话我倒立洗头!”老陈信誓旦旦道。

我懒得跟他BB,直接开始了 benchmark,跑的结果如下:

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

  • fortry: 86,261(100359-14098) ~ 114,457(100359+14098)
  • tryfor: 95,961(103216-7255) ~ 110,471(103216+7255)

我再调小(一般业务场景 for 循环次数都不会很多)下 for 循环的次数为 1000 ,结果也是差不多:

老陈一看傻了:“说好的性能影响呢?怎么没了?”

我直接一个javap,让老陈看看,其实两个实现在字节码层面没啥区别:

tryfor 的字节码

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

fortry 的字节码

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

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

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

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

并且还有下面一段话:

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

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

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

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

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

结果如下:

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

好了,我再总结下有关 try-catch 性能问题说法:

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

“好了,老陈你懂了没?”

“行啊yes,BB是一套一套的,走请你喝燕麦拿铁!” 老陈一把拉起我,我直接一个挣脱,“少来,我刚喝过咖啡,你那个倒立洗头,赶紧的!”我立马意识到老陈想岔开话题。

“洗洗洗,我们先喝个咖啡,晚上回去给你洗!”

晚上22点,老陈发来一张图片:

你别说,这头发至少比三毛多。

我是yes,我们下篇见~

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
Int’l Luxury Brands Embrace E-Commerce to Attract Chinese BuyersFastTrack Universität 2023莱比锡大学公立语言项目招生简章机器人长时间聊天会“失控”?微软限制每个问题只能问5遍为什么越乖的孩子,长大后越容易出现心理问题?打扰!这页PPT,有什么问题?北大教授:“伪专家”盛行不衰,这个社会出了什么问题?洗手台上出现了小黑点,是洗手台有问题还是我有问题?为什么美国通货膨胀对加拿大央行来说是个问题?“二十八画生”与“二十一回猛士”Bridging the Gap: Livestream Matchmaking for Rural Chinese我们家的炒股历程孩子乳头向内凹陷或呈一条裂缝样是什么问题?需要担心吗?蒋勋:我们的教育到底出了什么问题?2022: A Bad Year for China’s Film Industry数据仓库的性能问题及解决之道In China, Copycats are Trying to Cash in on ChatGPT Hype为什么要请一位经济学家谈论人口问题?「性生活越来越少,是我有问题,还是他有问题?」【波士顿最顶级公寓|紧邻Chinatown和Newbury Street|奢华大气|私人隐私|近绿线地铁】“以前的孩子也挨打挨骂,为什么没有心理问题?”看完那个想自杀的6岁女孩,终于明白了……储殷:北大辛德勇教授新年公开求职引起轰动,说明了什么严重问题?[评测]AMD Ryzen 9 7900/Ryzen 7 7700/Ryzen 5 7600 评测您想问ChatGPT什么问题?发给我们China Is Trying to Boost Fertility. Can Its Sperm Banks Keep Up?旧文:细颈瓶上台九年来 倒行逆施盘点为什么以前的孩子也挨打挨骂,却没有心理问题?答案值得深思……How Climate Change Is Disrupting China’s Cherry Blossom Season三星Galaxy S23 Ultra性能测试曝光,GPU性能亮眼【Career Forum|4.1】Fight the Career Winter in the Tech Industry!我已经不用 try catch 处理异常!太酸菜了!孩子肚子大, 显得前凸后翘,会不会有什么问题?从美敦力手中抢了25%的市场份额,它靠什么解决尿失禁的核心技术问题?中国标准证明美国新冠只死了6万支付宝二面:使用 try-catch 捕获异常会影响性能吗?大部分人都会答错!老了也要玩得大
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。