C C 程式設計 了解異常處理的系統開銷

2021-10-18 05:52:16 字數 1385 閱讀 3523

為了在執行時處理異常,程式要記錄大量的資訊:

讓我們先從你不使用任何異常處理特性也要付出的代價談起:

在理論上,你不能對這些代價進行選擇:異常是c++的一部分,c++編譯器必須支援異常也就是說,當你不用異常處理時你不能讓編譯器生產商消除這方面的開銷:

不過這只是理論,實際上大部分支援異常的編譯器生產商都允許你自由控制是否在生成的**裡包含進支援異常的內容:

使用異常處理的第二個開銷來自於try塊,無論何時使用它,也就是當你想能夠捕獲異常時,那你都得為此付出代價:不同的編譯器實現try塊的方法不同,所以編譯器與編譯器間的開銷也不一樣。粗略地估計,如果你使用try塊,**的尺寸將增加5%-10%並且執行速度也同比例減慢。這還是假設程式沒有丟擲異常,我這裡討論的只是在程式裡使用try塊的開銷。為了減少開銷,你應該避免使用無用的try塊。

編譯器為異常規格生成的**與它們為try塊生成的**一樣多,所以乙個異常規格一般花掉與try塊一樣多的系統開銷。什麼?你說你認為異常規格只是乙個規格而已,你認為它們不會產生**?那麼好,現在你應該對此有新的認識了。

在我們來到了問題的核心部分,看看丟擲異常的開銷。事實上我們不用太關心這個問題,因為異常是很少見的,這種事件的發生往往被描述為exceptional(異常的,罕見的)。80-20規則(參見條款m16)告訴我們這樣的事件不會對整個程式的效能造成太大的影響。但是我知道你仍舊好奇地想知道如果丟擲乙個異常到底會有多大的開銷,答案是這可能會比較大。與乙個正常的函式返回相比,通過丟擲異常從函式裡返回可能會慢三個數量級。這個開銷很大。但是僅僅當你丟擲異常時才會有這個開銷,一般不會發生。但是如果你用異常表示乙個比較普遍的狀況,例如完成對資料結構的遍歷或結束乙個迴圈,那你必須重新予以考慮。

不過請等一下,你問我是怎麼知道這些事情的呢?如果說支援異常對於大多數編譯器來說是乙個較新的特性,如果說不同的編譯器的異常方法也不同,那麼我如何能說程式的尺寸將增大5%-10%,它的速度也同比例減慢,而且如果有大量的異常被丟擲,程式執行速度會呈數量級的減慢呢?答案是令人驚恐的:一些傳聞和一些基準測試(benchmarks)(參見條款m23)。事實是大部分人包括編譯器生產商在異常處理方面幾乎沒有什麼經驗,所以儘管我們知道異常確實會帶來開銷,卻很難**出開銷的準確數量。

謹慎的做法是對本條款所敘述的開銷有了解,但是不深究具體的數量(即定性不定量譯者注)。不論異常處理的開銷有多大我們都得堅持只有必須付出時才付出的原則。為了使你的異常開銷最小化,只要可能就盡量採用不支援異常的方法編譯程式,把使用try塊和異常規格限制在你確實需要它們的地方,並且只有在確為異常的情況下(exceptional)才丟擲異常。如果你在效能上仍舊有問題,總體評估一下你的軟體以決定異常支援是否是乙個起作用的因素。如果是,那就考慮選擇其它的編譯器,能在c++異常處理方面具有更高實現效率的編譯器。

網路程式設計的異常及處理

網路程式設計不只是編寫網路 主機 程序都正常時能良好工作的程序,更重要的是客戶主機崩潰 客戶程序崩潰網路異常時怎麼處理。accept被訊號中斷 accept以及套接字上的i o可能被訊號打斷,並返回eintr作為結果,必須處理該返回值並且適當時候再次呼叫。for else connect被訊號中斷 ...

系統對異常的處理使用統一的異常處理流程

系統對異常的處理使用統一的異常處理流程。1 自定義異常型別。2 自定義錯誤 及錯誤資訊。3 對於可預知的異常由程式設計師在 中主動拋出自定義異常型別的異常,丟擲異常時需要指定錯誤 4 對於不可預知的異常 執行時異常 由springmvc統一捕獲exception型別的異常,由統一的異常捕獲類來解析 ...

C 網路程式設計中的異常處理

目錄 l摘要 l 網路程式設計中異常出現場景 l 網路程式設計中的異常處理 l 小結 摘要 異常的處理是為了保證程式盡量在不可預知的意外情況正常執行,同時異常的處理也是比較繁瑣的過程。在網路程式設計中,不可預知的情況更多,使得開發者在程式設計時需要編寫大量的異常處理 本文介紹了 c 中一種簡單的異常...