“你看著這鬼代碼,竟然在 for 循環(huán)里面搞了個 try-catch,不知道try-catch有性能損耗嗎?”
老陳煞有其事地指著屏幕里的代碼:
for(inti=0;i5000;?i++)?{ ?????try?{ ?????????dosth ?????}?catch?(Exception?e)?{ ?????????e.printStackTrace(); ?????} ?}
我探過頭去看了眼代碼,“那老陳你覺得該怎么改?”
“當然是把 try-catch 提到外面?。 崩详惸X子都不轉(zhuǎn)一下,脫口而出。
“你是不是傻?且不說性能,這代碼的目的明顯是讓循環(huán)內(nèi)部單次調(diào)用出錯不影響循環(huán)的運行,你其到外面業(yè)務(wù)邏輯不就變了嗎!”
老陳撓了撓他的地中海,“好像也是??!”
“回過頭來,catch 整個 for 循環(huán)和在循環(huán)內(nèi)部 catch,在不出錯的情況下,其實性能差不多?!?我喝一口咖啡不經(jīng)意地提到,準備在老陳前面秀一下。
“啥意思?”老陳有點懵地看著我,“try-catch是有性能損耗的,我可是看過網(wǎng)上資料的!”
果然,老陳上鉤了,我二話不說直接打開 idea,一頓操作敲了以下代碼:
publicclassTryCatchTest{ @Benchmark publicvoidtryfor(Blackholeblackhole){ try{ for(inti=0;i5000;?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,看到?jīng)],老陳,我把 try-catch 從 for 循環(huán)里面提出來跟在for循環(huán)里面做個對比跑一下,你猜猜兩個差多少?”
“切,肯定 tryfor 性能好,想都不用想,不是的話我倒立洗頭!”老陳信誓旦旦道。
我懶得跟他BB,直接開始了 benchmark,跑的結(jié)果如下:
可以看到,兩者的性能(數(shù)字越大越好)其實差不多:
fortry: 86,261(100359-14098) ~ 114,457(100359+14098)
tryfor: 95,961(103216-7255) ~ 110,471(103216+7255)
我再調(diào)小(一般業(yè)務(wù)場景 for 循環(huán)次數(shù)都不會很多)下 for 循環(huán)的次數(shù)為 1000 ,結(jié)果也是差不多:
老陳一看傻了:“說好的性能影響呢?怎么沒了?”
我直接一個javap,讓老陳看看,其實兩個實現(xiàn)在字節(jié)碼層面沒啥區(qū)別:
tryfor 的字節(jié)碼
異常表記錄的是 0 - 20 行,如果這些行里面的代碼出現(xiàn)問題,直接跳到 23 行處理。
fortry 的字節(jié)碼
差別也就是異常表的范圍小點,包的是 9-14 行,其它跟 tryfor 都差不多。
圖片
所以從字節(jié)碼層面來看,沒拋錯兩者的執(zhí)行效率其實沒啥差別。
“那為什么網(wǎng)上流傳著try-catch會有性能問題的說法???”老陳覺得非常奇怪。
這個說法確實有,在《Effective Java》這本書里就提到了 try-catch 性能問題:
并且還有下面一段話:
圖片
正所謂聽話不能聽一半,以前讀書時候最怕的就是一知半解,因為完全理解選擇題能選對,完全不懂蒙可能蒙對,一知半解必定選到錯誤的選項!
《Effective Java》書中說的其實是不要用 try-catch 來代替正常的代碼,書中的舉例了正常的 for 循環(huán)肯定這樣實現(xiàn):
但有個臥龍偏偏不這樣實現(xiàn),要通過 try-catch 拐著彎來實現(xiàn)循環(huán):
這操作我只能說有點逆天,這兩個實現(xiàn)的對比就有性能損耗了。
我們直接再跑下有try-catch 的代碼和沒 try-catch的 for 循環(huán)區(qū)別,代碼如下:
結(jié)果如下:
+-差不多,直接看前面的分數(shù)對比,沒有 ry-catch 的性能確實好些,這也和書中說的 try-catch 會影響 JVM 一些特定的優(yōu)化說法吻合,但是具體沒有說影響哪些優(yōu)化,我猜測可能是指令重排之類的。
好了,我再總結(jié)下有關(guān) try-catch 性能問題說法:
try-catch 相比較沒 try-catch,確實有一定的性能影響,但是旨在不推薦我們用 try-catch 來代替正常能不用 try-catch 的實現(xiàn),而不是不讓用 try-catch。
for循環(huán)內(nèi)用 try-catch 和用 try-catch 包裹整個 for 循環(huán)性能差不多,但是其實兩者本質(zhì)上是業(yè)務(wù)處理方式的不同,跟性能扯不上關(guān)系,關(guān)鍵看你的業(yè)務(wù)流程處理。
雖然知道try-catch會有性能影響,但是業(yè)務(wù)上不需要避諱其使用,業(yè)務(wù)實現(xiàn)優(yōu)先(只要不是書中舉例的那種逆天代碼就行),非特殊情況下性能都是其次,有意識地避免大范圍的try-catch,只 catch 需要的部分即可(沒把握全 catch 也行,代碼安全執(zhí)行第一)。
審核編輯:劉清
-
JAVA
+關(guān)注
關(guān)注
20文章
2989瀏覽量
109539 -
JVM
+關(guān)注
關(guān)注
0文章
160瀏覽量
12616
原文標題:支付寶二面:使用 try-catch 捕獲異常會影響性能嗎?大部分人都會答錯!
文章出處:【微信號:小林coding,微信公眾號:小林coding】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
普源DHO5104波形捕獲率對偶發(fā)故障診斷的影響

泰克示波器高級觸發(fā)功能捕獲異常信號的5種方法

HarmonyOS5云服務(wù)技術(shù)分享--云數(shù)據(jù)庫使用指南
HarmonyOS5云服務(wù)技術(shù)分享--ArkTS調(diào)用函數(shù)
HarmonyOS5云服務(wù)技術(shù)分享--退出登錄文檔問題
使用STM32捕獲PWM時同時捕獲2個通道時會出現(xiàn)捕獲的頻率值不準確的問題,是什么原因?qū)е碌模?/a>
使用STM32捕獲PWM時同時捕獲2個通道時會出現(xiàn)捕獲的頻率值不準,為什么?
泰克MDO3052示波器波形捕獲率評測

最新 HUAWEI DevEco Studio 調(diào)試技巧
ADS1291測試中經(jīng)常會出現(xiàn)R波變小的情況,為什么?
LM98640調(diào)試過程中發(fā)現(xiàn)時常會出現(xiàn)配置不正確的現(xiàn)象,怎么解決?
是德DSOX4032A示波器波形捕獲率

評論