“yes,你看着这鬼代码,竟然在 for 循环里面搞了个 try-catch ,不知道try-catch 有性能损耗吗?”老陈煞有其事地指着屏幕里的代码: for (int i = 0; i < 5000; i++) { 我探过头去看了眼代码,“那老陈你觉得该怎么改?” “当然是把 try-catch 提到外面啊!”老陈脑子都不转一下,脱口而出。“你是不是傻?且不说性能,这代码的目的明显是让循环内部单次调用出错不影响循环的运行,你其到外面业务逻辑不就变了吗!” 老陈挠了挠他的地中海,“好像也是啊!” “回过头来,catch 整个 for 循环和在循环内部 catch,在不出错的情况下,其实性能差不多。” 我喝一口咖啡不经意地提到,准备在老陈前面秀一下。 “啥意思?”老陈有点懵地看着我,“ try-catch 是有性能损耗的,我可是看过网上资料的!”果然,老陈上钩了,我二话不说直接打开 idea,一顿操作敲了以下代码: public class TryCatchTest { “BB 不如 show code,看到没,老陈,我把 try-catch 从 for 循环里面提出来跟在for循环里面做个对比跑一下,你猜猜两个差多少?”“切,肯定 tryfor 性能好,想都不用想,不是的话我倒立洗头!”老陈信誓旦旦道。 我懒得跟他BB,直接开始了 benchmark,跑的结果如下: 可以看到,两者的性能(数字越大越好)其实差不多:
我再调小(一般业务场景 for 循环次数都不会很多)下 for 循环的次数为 1000 ,结果也是差不多: 老陈一看傻了:“说好的性能影响呢?怎么没了?” 我直接一个javap,让老陈看看,其实两个实现在字节码层面没啥区别:
异常表记录的是 0 - 20 行,如果这些行里面的代码出现问题,直接跳到 23 行处理。
差别也就是异常表的范围小点,包的是 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 性能问题说法:
“好了,老陈你懂了没?” “行啊yes,BB是一套一套的,走请你喝燕麦拿铁!” 老陈一把拉起我,我直接一个挣脱,“少来,我刚喝过咖啡,你那个倒立洗头,赶紧的!”我立马意识到老陈想岔开话题。 “洗洗洗,我们先喝个咖啡,晚上回去给你洗!” 晚上22点,老陈发来一张图片: 你别说,这头发至少比三毛多。 微信8.0将好友放开到了一万,小伙伴可以加我大号了,先到先得,再满就真没了 扫描下方二维码即可加我微信啦, 2023,抱团取暖,一起牛逼。 推荐阅读
上一篇:拿到CSDN账号的一个小思路 下一篇:果壳官方app终于更新了!(什么,果壳竟然有app? |