日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

啪啪打脸!领导说:try-catch要放在循环体外!

發布時間:2025/3/11 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 啪啪打脸!领导说:try-catch要放在循环体外! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是我的第?206?期分享

作者 | 王磊

來源 | Java中文社群(ID:javacn666)

轉載請聯系授權(微信ID:GG_Stone)

哈嘍,親愛的小伙伴們,技術學磊哥,進步沒得說!歡迎來到新一期的性能解讀系列,我是磊哥。

今天給大家帶來的是關于 try-catch 應該放在循環體外,還是放在循環體內的文章,我們將從性能業務場景分析這兩個方面來回答此問題。

很多人對 try-catch?有一定的誤解,比如我們經常會把它(try-catch)和“低性能”直接畫上等號,但對 try-catch 的本質(是什么)卻缺少著最基礎的了解,因此我們也會在本篇中對 try-catch 的本質進行相關的探索

小貼士:我會盡量用代碼和評測結果來證明問題,但由于本身認知的局限,如有不當之處,請讀者朋友們在評論區指出。

性能評測

話不多說,我們直接來開始今天的測試,本文我們依舊使用 Oracle 官方提供的 JMH(Java Microbenchmark Harness,JAVA 微基準測試套件)來進行測試。

首先在 pom.xml 文件中添加 JMH 框架,配置如下:

<!--?https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core?--> <dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-core</artifactId><version>{version}</version> </dependency>

完整測試代碼如下:

import?org.openjdk.jmh.annotations.*; import?org.openjdk.jmh.runner.Runner; import?org.openjdk.jmh.runner.RunnerException; import?org.openjdk.jmh.runner.options.Options; import?org.openjdk.jmh.runner.options.OptionsBuilder;import?java.util.concurrent.TimeUnit;/***?try?-?catch?性能測試*/ @BenchmarkMode(Mode.AverageTime)?//?測試完成時間 @OutputTimeUnit(TimeUnit.NANOSECONDS) @Warmup(iterations?=?1,?time?=?1,?timeUnit?=?TimeUnit.SECONDS)?//?預熱?1?輪,每次?1s @Measurement(iterations?=?5,?time?=?5,?timeUnit?=?TimeUnit.SECONDS)?//?測試?5?輪,每次?3s @Fork(1)?//?fork?1?個線程 @State(Scope.Benchmark) @Threads(100) public?class?TryCatchPerformanceTest?{private?static?final?int?forSize?=?1000;?//?循環次數public?static?void?main(String[]?args)?throws?RunnerException?{//?啟動基準測試Options?opt?=?new?OptionsBuilder().include(TryCatchPerformanceTest.class.getSimpleName())?//?要導入的測試類.build();new?Runner(opt).run();?//?執行測試}@Benchmarkpublic?int?innerForeach()?{int?count?=?0;for?(int?i?=?0;?i?<?forSize;?i++)?{try?{if?(i?==?forSize)?{throw?new?Exception("new?Exception");}count++;}?catch?(Exception?e)?{e.printStackTrace();}}return?count;}@Benchmarkpublic?int?outerForeach()?{int?count?=?0;try?{for?(int?i?=?0;?i?<?forSize;?i++)?{if?(i?==?forSize)?{throw?new?Exception("new?Exception");}count++;}}?catch?(Exception?e)?{e.printStackTrace();}return?count;} }

以上代碼的測試結果為:


從以上結果可以看出,程序在循環 1000 次的情況下,單次平均執行時間為:

  • 循環內包含 try-catch 的平均執行時間是 635 納秒 ±75 納秒,也就是 635 納秒上下誤差是 75 納秒;

  • 循環外包含 try-catch 的平均執行時間是 630 納秒,上下誤差 38 納秒。

也就是說,在沒有發生異常的情況下,除去誤差值,我們得到的結論是:try-catch 無論是在 for?循環內還是 ?for?循環外,它們的性能相同,幾乎沒有任何差別

try-catch的本質

要理解 try-catch 的性能問題,必須從它的字節碼開始分析,只有這樣我能才能知道 try-catch 的本質到底是什么,以及它是如何執行的。

此時我們寫一個最簡單的 try-catch 代碼:

public?class?AppTest?{public?static?void?main(String[]?args)?{try?{int?count?=?0;throw?new?Exception("new?Exception");}?catch?(Exception?e)?{e.printStackTrace();}} }

然后使用 javac?生成字節碼之后,再使用 javap -c AppTest?的命令來查看字節碼文件:

??javap?-c?AppTest? 警告:?二進制文件AppTest包含com.example.AppTest Compiled?from?"AppTest.java" public?class?com.example.AppTest?{public?com.example.AppTest();Code:0:?aload_01:?invokespecial?#1??????????????????//?Method?java/lang/Object."<init>":()V4:?returnpublic?static?void?main(java.lang.String[]);Code:0:?iconst_01:?istore_12:?new???????????#2??????????????????//?class?java/lang/Exception5:?dup6:?ldc???????????#3??????????????????//?String?new?Exception8:?invokespecial?#4??????????????????//?Method?java/lang/Exception."<init>":(Ljava/lang/String;)V11:?athrow12:?astore_113:?aload_114:?invokevirtual?#5??????????????????//?Method?java/lang/Exception.printStackTrace:()V17:?returnException?table:from????to??target?type0????12????12???Class?java/lang/Exception }

從以上字節碼中可以看到有一個異常表:

Exception?table:from????to??target?type0????12????12???Class?java/lang/Exception

參數說明:

  • from:表示 try-catch 的開始地址;

  • to:表示 try-catch 的結束地址;

  • target:表示異常的處理起始位;

  • type:表示異常類名稱。

從字節碼指令可以看出,當代碼運行時出錯時,會先判斷出錯數據是否在 from?到 to?的范圍內,如果是則從 target?標志位往下執行,如果沒有出錯,直接 goto?到 return。也就是說,如果代碼不出錯的話,性能幾乎是不受影響的,和正常的代碼的執行邏輯是一樣的。

業務情況分析

雖然 try-catch 在循環體內還是循環體外的性能是類似的,但是它們所代碼的業務含義卻完全不同,例如以下代碼:

public?class?AppTest?{public?static?void?main(String[]?args)?{System.out.println("循環內的執行結果:"?+?innerForeach());System.out.println("循環外的執行結果:"?+?outerForeach());}//?方法一public?static?int?innerForeach()?{int?count?=?0;for?(int?i?=?0;?i?<?6;?i++)?{try?{if?(i?==?3)?{throw?new?Exception("new?Exception");}count++;}?catch?(Exception?e)?{e.printStackTrace();}}return?count;}//?方法二public?static?int?outerForeach()?{int?count?=?0;try?{for?(int?i?=?0;?i?<?6;?i++)?{if?(i?==?3)?{throw?new?Exception("new?Exception");}count++;}}?catch?(Exception?e)?{e.printStackTrace();}return?count;} }

以上程序的執行結果為:

java.lang.Exception: new Exception

at com.example.AppTest.innerForeach(AppTest.java:15)

at com.example.AppTest.main(AppTest.java:5)

java.lang.Exception: new Exception

at com.example.AppTest.outerForeach(AppTest.java:31)

at com.example.AppTest.main(AppTest.java:6)

循環內的執行結果:5

循環外的執行結果:3

可以看出在循環體內的 try-catch 在發生異常之后,可以繼續執行循環;而循環外的 try-catch 在發生異常之后會終止循環。

因此我們在決定?try-catch 究竟是應該放在循環內還是循環外,不取決于性能(因為性能幾乎相同),而是應該取決于具體的業務場景

例如我們需要處理一批數據,而無論這組數據中有哪一個數據有問題,都不能影響請他組的正常執行,此時我們可以把 try-catch 放置在循環體內;而當我們需要計算一組數據的合計值時,只要有一組數據有誤,我們就需要終止執行,并拋出異常,此時我們需要將 try-catch 放置在循環體外來執行。

總結

本文我們測試了 try-catch 放在循環體內和循環體外的性能,發現二者在循環很多次的情況下性能幾乎是一致的。然后我們通過字節碼分析,發現只有當發生異常時,才會對比異常表進行異常處理,而正常情況下則可以忽略 try-catch 的執行。但在循環體內還是循環體外使用 try-catch,對于程序的執行結果來說是完全不同的,因此我們應該從實際的業務出發,來決定到 try-catch 應該存放的位置,而非性能考慮

往期推薦

阿里巴巴為什么讓初始化集合時必須指定大小?

局部變量竟然比全局變量快 5 倍?

關注公眾號發送”進群“,磊哥拉你進讀者群。

總結

以上是生活随笔為你收集整理的啪啪打脸!领导说:try-catch要放在循环体外!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲一区二区三区四区电影 | 色八戒av| 欧美专区亚洲专区 | 国产乱码精品一区二区 | 西西久久 | 91调教视频 | 亚洲成a人片77777精品 | 精品国产一区二区三区久久狼黑人 | 少妇久久精品 | 本道久久 | 中文字幕日本在线观看 | 中文字幕在线观看不卡 | 91导航| 日韩在线观看视频一区二区 | 成人高潮片免费网站 | 国产精品成人免费精品自在线观看 | 亚洲成av人片在www色猫咪 | 国产黄色网络 | 精品国产99一区二区乱码综合 | 国产aⅴ激情无码久久久无码 | 黄色片免费观看 | aaa人片在线 | 一级片免费网址 | 日本黄色大片免费看 | 永久国产| 五月天国产视频 | www.黄色国产| 99久久久久无码国产精品 | 97播播 | 欧美黄色大片在线观看 | 波多野结衣久久精品 | 古装做爰无遮挡三级聊斋艳谭 | www.精品在线| 91麻豆产精品久久久久久夏晴子 | 欧美日本一二三区 | 日韩在线视频一区 | 亚欧在线观看 | 国产午夜伦理 | 亚洲免费视频一区二区三区 | 一级黄色大片视频 | 日日操狠狠操 | 国产成人资源 | 性欧美一区二区三区 | 国产黄色网络 | 黄色的毛片 | 中文字字幕在线中文 | 中文字幕av网站 | 91色视频在线 | 亚洲一区精品视频在线观看 | 成人福利视频网 | 精品久久影院 | 国产极品在线播放 | 国内自拍2020 | 亚洲成人av免费在线观看 | 色婷婷综合久久久久中文一区二区 | 亚洲免费av在线 | 欧美视频日韩视频 | 成人夜视频 | 99热91 | 91成人观看| 亚洲97色| 天天干视频 | 精品国模一区二区三区 | 中文字幕第88页 | 成人看片黄a免费看视频 | 人人爽夜夜爽 | 性五月天 | 久久免费片 | 97人妻一区二区精品免费视频 | 宅男视频在线免费观看 | 少妇人妻真实偷人精品视频 | 久久精品五月天 | 欧美v在线| asian日本肉体pics| 日本中文字幕网 | 国产精品久久久久久久毛片 | 又色又爽又黄gif动态图 | 成人免费视频一区二区三区 | 人妻在线一区 | 免费成人黄色网址 | 日韩精品一二三四区 | 亚洲国产毛片 | 日韩久久影院 | 91理论片午午伦夜理片久久 | 国产美女作爱全过程免费视频 | av一区二区不卡 | 国产不卡a | 久青草视频在线观看 | 永久免费av网站 | 香蕉久久国产 | 夫の上司に犯波多野结衣853 | 亚洲精品h | av第一福利大全导航 | 91丝袜国产在线播放 | 国产精品一区二区视频 | 日本韩国中文字幕 | 免费黄色一区二区 | 污污av | 日韩小视频在线观看 |