Try Catch真的會影響程式效能嗎

2021-06-19 12:08:46 字數 2504 閱讀 1658

**:    

很多帖子都分析過try-catch的機制,以及其對效能的影響。

但是並沒有證據證明,try-catch過於損耗了系統的效能,尤其是在託管環境下。記得園子裡有位網友使用stopwatch分析過try-catch在不同情況下,與無try-catch的**相比,**執行的時間指標,結果並沒有很大差異。

下面我來結合il分析一下try-catch吧。

● 機制分析

.net 中基本的異常捕獲與處理機制是由try…catch…finally塊來完成的,它們分別完成了異常的監測、捕獲與處理工作。乙個try塊可以對應零個或多個catch塊,可以對應零個或乙個finally塊。不過沒有catch的try似乎沒有什麼意義,如果try對應了多個catch,那麼監測到異常後,clr會自上而下搜尋catch塊的**,並通過異常過濾器篩選對應的異常,如果沒有找到,那麼clr將沿著呼叫堆疊,向更高層搜尋匹配的異常,如果已到堆疊頂部依然沒有找到對應的異常,就會丟擲未處理的異常了,這時catch塊中的**並不會被執行。所以距離try最近的catch塊將最先被遍歷到。

如有以下**:

try 

catch (formatexception ex1)

catch (nullreferenceexception ex2)

finally

對應il如下:

.method private hidebysig instance void form1_load(object sender,

class [mscorlib]system.eventargs e) cil managed

// end of method form1::form1_load

末尾的幾行**揭示出il是怎樣處理異常處理的。最後三行的每乙個item被稱作exception handing clause,ehc組成exception handing table,eht與正常**之間由ret返回指令隔開。

可以看出,formatexception排列在eht的第一位。

當**成功執行或反之而返回後,clr會遍歷eht:

1. 如果丟擲異常, clr會根據丟擲異常的**的「位址」找到對應的ehc(il_0001 to il_0010為檢測**的範圍),這個例子中clr將找到2條ehc,formatexception會最先被遍歷到,且為適合的ehc。

2. 如果返回的**位址在il_0001 to il_0029內,那麼還會執行finally handleril_0029 to il_0033中的**,不管是否因成功執行**而返回

事實上,catch與finally的遍歷工作是分開進行的,如上文所言,clr首先做的是遍歷catch,當找到合適的catch塊後,再遍歷與之對應finally;而且這個過程會遞迴進行至少兩次,因為編譯器將c#的try…catch…finally翻譯成il中的兩層巢狀。

當然如果沒有找到對應的catch塊,那麼clr會直接執行finally,然後立即中斷所有執行緒。finally塊中的**肯定會被執行,無論try是否檢測到了異常。

● 改進建議

由上面的內容可以得出:

如果使用了「try-catch」,且捕獲到了異常,clr做的只不過是遍歷exception handing table中的catch項;然後再次遍歷exception handing table中的finally項,所用時間幾乎都花費在遍歷exception handing table上;而如果沒有捕獲到異常,clr只是遍歷exception handing table中的finally項,所需時間微乎其微。

而「try-catch」遍歷後的執行對應操作所用時間,則根據你的具體**所定,「try-catch」引起的只是監控與觸發,不應將這部分的**時間也算「try-catch」的消耗。

所以,可以從效能和**評審兩方面考慮,一般建議有以下幾點準則:

1.盡量給clr乙個明確的異常資訊,不要使用exception去過濾異常

2.盡量不要將try…catch寫在迴圈中

3. try盡量少的**,如果有必要可以使用多個catch塊,並且將最有可能丟擲的異常型別,書寫在距離try最近的位置

4.不要只宣告乙個exception物件,而不去處理它。這樣做白白增加了exception handing table的長度。

5.使用效能計數器實用工具的「clr exceptions」檢測異常情況,並適當優化

6.使用成員的try-parse模式,如果丟擲異常,那麼用false代替它

結論,try-catch雖然會消費一點時間,但程式人員大可不必談虎色變,通過上面的分析,與其說「try-catch」會損耗或影響效能,不如說「try-catch」與其他**一樣,只是效能的普通消費者,但出於**書寫評審方面的考慮,還是盡量關照一下「try-catch」吧。

C 中Try Catch語句真的影響程式效能嗎?

很多帖子都分析過try catch的機制,以及其對效能的影響。但是並沒有證據證明,try catch過於損耗了系統的效能,尤其是在託管環境下。記得園子裡有位使用stopwatch分析過try catch在不同情況下,與無try catch的 相比,執行的時間指標,結果並沒有很大差異。下面我來結合il...

try catch 的效能影響

現象 大量try.catch.newtonsoft.json序列化速度明顯降低 9000ms 250ms 疑問 大量try.catch.影響效能?主要效能消耗在於跳轉到catch塊?準則 不要將try.catch.用於處理 邏輯跳轉,僅用於常規異常處理 不要濫用try.catch.總結 try.ca...

try catch對Spring事務的影響

一 spring 的預設事務機制,當出現unchecked異常時候回滾,checked異常的時候不會回滾。異常中unchecked異常包括error和runtime異常。需要try catch或向上丟擲的異常,為checked異常比如ioexception,也就是說程式丟擲runtime異常的時候才...