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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

抛出异常–缓慢而丑陋

發(fā)布時(shí)間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 抛出异常–缓慢而丑陋 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這篇文章是關(guān)于歷史經(jīng)驗(yàn)以及最近應(yīng)用的性能優(yōu)化技術(shù)的。 幾年前,我在特定的應(yīng)用程序中發(fā)誓,我不得不發(fā)現(xiàn)隱藏在真正聰明的工程“技術(shù)”之下的無(wú)證行為。

它是一個(gè)典型的用于發(fā)票的單片Java EE應(yīng)用程序。 最好忘記確切的代碼,但是我記得開(kāi)發(fā)人員已經(jīng)找到了一種真正聰明的方法來(lái)控制業(yè)務(wù)流程。

流程的一部分通常是無(wú)休止的if-then-else混亂,但使事情更加“令人興奮”的是,這些檢查的一些隨機(jī)元素被埋入了自定義java.lang.RuntimeException處理機(jī)制中。 因此,您可能具有類似于以下內(nèi)容的代碼:

if (invoice.overdue()) {if (invoice.getCustomer().isKeyCustomer())throw new InvoiceOverdueException(InvoiceOverdueException.KEY_CUSTOMER);elsedoSomething(); } else {if (invoice.getDueAmount() > BIG_AMOUNT)if (invoice.getCustomer().isKeyCustomer())//be silentelsethrow new InvoiceExceededException(invoice.getDueAmount()); }

并非像上述那樣簡(jiǎn)短易懂的塊,而是在整個(gè)應(yīng)用程序中散布了數(shù)千行代碼。

我想你可能同意我的觀點(diǎn),這是使自己不可或缺的一種好方法。 有人會(huì)以一種瘋狂的方式來(lái)理解應(yīng)用程序?yàn)槭裁磿?huì)如此。

我回想起最近的Plumbr優(yōu)化任務(wù)帶來(lái)的經(jīng)驗(yàn)。 我想說(shuō)我們的代碼沒(méi)有使用前面案例描述的異常,但是不幸的是,這并非完全正確。 一個(gè)特定的方法仍然在代碼的常規(guī)流程中構(gòu)造并拋出RuntimeException 。 由于這個(gè)特定模塊的性能異常,我只發(fā)現(xiàn)了這個(gè)孤獨(dú)的反派。

通常,僅在遇到意外問(wèn)題時(shí)才會(huì)引發(fā)異常。 因此,我們不希望每個(gè)線程每秒拋出數(shù)千個(gè)異常。 但是像我一樣,您可能會(huì)發(fā)現(xiàn)一種對(duì)異常事件使用異常的方法。

我之所以只找到罪魁禍?zhǔn)?#xff0c;是因?yàn)檫@是特定圖形遍歷算法中經(jīng)常使用的代碼塊,因此從中擠出最后一毫秒至關(guān)重要。 立即刪除異常處理使此代碼塊的完成速度提高了100倍以上。

這可能使您想知道–為什么異常處理速度很慢? 最慢的部分與構(gòu)造異常有關(guān)。 或者,更確切地說(shuō),是java.lang.Throwable的任何子類。

如果您還記得的話,所有構(gòu)造函數(shù)都會(huì)通過(guò)調(diào)用super()來(lái)調(diào)用對(duì)超類默認(rèn)構(gòu)造函數(shù)的調(diào)用。 如果您未自行指定此調(diào)用,則編譯器會(huì)友好地將其添加到字節(jié)碼本身中。 無(wú)論如何,當(dāng)查看java.lang.Throwable源代碼時(shí),您會(huì)看到答案盯著您:

public Throwable() {fillInStackTrace();}public synchronized Throwable fillInStackTrace() {if (stackTrace != null ||backtrace != null /* Out of protocol state */ ) {fillInStackTrace(0);stackTrace = UNASSIGNED_STACK;}return this;}private native Throwable fillInStackTrace(int dummy);

因此,每次創(chuàng)建新的Throwable()時(shí),最終都會(huì)通過(guò)本機(jī)調(diào)用填充整個(gè)堆棧跟蹤。 如果您不認(rèn)為這很慢,請(qǐng)執(zhí)行以下jmh微基準(zhǔn)測(cè)試,以驗(yàn)證創(chuàng)建異常的費(fèi)用比構(gòu)造常規(guī)對(duì)象的費(fèi)用高數(shù)百倍:

@BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) public class NewExceptionTest {@GenerateMicroBenchmarkpublic Object baseline() {return new Object();}@GenerateMicroBenchmarkpublic Object exceptional() {return new RuntimeException();} }Benchmark Mode Thr Cnt Sec Mean Mean error Units j.NewExceptionTest.baseline avgt 1 5 5 3.275 0.029 nsec/op j.NewExceptionTest.exceptional avgt 1 5 5 1329.266 8.675 nsec/op

總而言之,在特殊情況下,名稱應(yīng)表示例外。 如果您開(kāi)始濫用該概念,那么您要么使代碼不可讀,要么開(kāi)始遭受性能問(wèn)題的困擾。 至少,我保證您會(huì)從中獲得大量的負(fù)面因果報(bào)應(yīng)。

參考: 拋出異常–我們的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上緩慢而丑陋 。

翻譯自: https://www.javacodegeeks.com/2013/08/throwing-exceptions-slow-and-ugly.html

總結(jié)

以上是生活随笔為你收集整理的抛出异常–缓慢而丑陋的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。