我是柠檬哥,专注编程知识学习和分享。 欢迎关注程序员柠檬橙,编程路上不迷路 私信发送1024打包下载10个G编程资源学习资料 私信发送001获取阿里大神LeetCode刷题笔记 私信发送002获取获取谷歌公司编程代码规范 私信发送003获取10个精美简历模板PDF和Word版 私信发送004获取100道精选C面试题和答案word版 私信发送005获取获取谷歌LeetCode算法笔记 你看着这鬼代码,竟然在for循环里面搞了个trycatch,不知道trycatch有性能损耗吗? 老陈煞有其事地指着屏幕里的代码:for(inti0;i5000;i){try{dosth}catch(Exceptione){e。printStackTrace();}} 我探过头去看了眼代码,那老陈你觉得该怎么改? 当然是把trycatch提到外面啊!老陈脑子都不转一下,脱口而出。 你是不是傻?且不说性能,这代码的目的明显是让循环内部单次调用出错不影响循环的运行,你其到外面业务逻辑不就变了吗! 老陈挠了挠他的地中海,好像也是啊! 回过头来,catch整个for循环和在循环内部catch,在不出错的情况下,其实性能差不多。我喝一口咖啡不经意地提到,准备在老陈前面秀一下。 啥意思?老陈有点懵地看着我,trycatch是有性能损耗的,我可是看过网上资料的! 果然,老陈上钩了,我二话不说直接打开idea,一顿操作敲了以下代码:publicclassTryCatchTest{Benchmarkpublicvoidtryfor(Blackholeblackhole){try{for(inti0;i5000;i){blackhole。consume(i);}}catch(Exceptione){e。printStackTrace();}}Benchmarkpublicvoidfortry(Blackholeblackhole){for(inti0;i5000;i){try{blackhole。consume(i);}catch(Exceptione){e。printStackTrace();}}}} BB不如showcode,看到没,老陈,我把trycatch从for循环里面提出来跟在for循环里面做个对比跑一下,你猜猜两个差多少? 切,肯定tryfor性能好,想都不用想,不是的话我倒立洗头!老陈信誓旦旦道。 我懒得跟他BB,直接开始了benchmark,跑的结果如下: 可以看到,两者的性能(数字越大越好)其实差不多:fortry:86,261(10035914098)114,457(10035914098)tryfor:95,961(1032167255)110,471(1032167255) 我再调小(一般业务场景for循环次数都不会很多)下for循环的次数为1000,结果也是差不多: 老陈一看傻了:说好的性能影响呢?怎么没了? 我直接一个javap,让老陈看看,其实两个实现在字节码层面没啥区别: tryfor的字节码 异常表记录的是020行,如果这些行里面的代码出现问题,直接跳到23行处理。 fortry的字节码 差别也就是异常表的范围小点,包的是914行,其它跟tryfor都差不多。 所以从字节码层面来看,没抛错两者的执行效率其实没啥差别。 那为什么网上流传着trycatch会有性能问题的说法啊?老陈觉得非常奇怪。 这个说法确实有,在《EffectiveJava》这本书里就提到了trycatch性能问题: 并且还有下面一段话: 正所谓听话不能听一半,以前读书时候最怕的就是一知半解,因为完全理解选择题能选对,完全不懂蒙可能蒙对,一知半解必定选到错误的选项! 《EffectiveJava》书中说的其实是不要用trycatch来代替正常的代码,书中的举例了正常的for循环肯定这样实现: 但有个卧龙偏偏不这样实现,要通过trycatch拐着弯来实现循环: 这操作我只能说有点逆天,这两个实现的对比就有性能损耗了。 我们直接再跑下有trycatch的代码和没trycatch的for循环区别,代码如下: 结果如下: 差不多,直接看前面的分数对比,没有rycatch的性能确实好些,这也和书中说的trycatch会影响JVM一些特定的优化说法吻合,但是具体没有说影响哪些优化,我猜测可能是指令重排之类的。 好了,我再总结下有关trycatch性能问题说法:trycatch相比较没trycatch,确实有一定的性能影响,但是旨在不推荐我们用trycatch来代替正常能不用trycatch的实现,而不是不让用trycatch。for循环内用trycatch和用trycatch包裹整个for循环性能差不多,但是其实两者本质上是业务处理方式的不同,跟性能扯不上关系,关键看你的业务流程处理。虽然知道trycatch会有性能影响,但是业务上不需要避讳其使用,业务实现优先(只要不是书中举例的那种逆天代码就行),非特殊情况下性能都是其次,有意识地避免大范围的trycatch,只catch需要的部分即可(没把握全catch也行,代码安全执行第一)。 好了,老陈你懂了没? 行啊,BB是一套一套的,走请你喝燕麦拿铁!老陈一把拉起我,我直接一个挣脱,少来,我刚喝过咖啡,你那个倒立洗头,赶紧的!我立马意识到老陈想岔开话题。 洗洗洗,我们先喝个咖啡,晚上回去给你洗! 晚上22点,老陈发来一张图片: 你别说,这头发至少比三毛多。 文章来源于yes的练级攻略,作者是Yes呀