2010-02-02 97 views
7

這是極其緩慢:DivideByZeroException太慢

try 
{ 
    x = k/y; 
} 
catch (DivideByZeroException) { } 

這是約5倍速度更快:

if (y > 0) x = k/y; 

任何人能告訴我爲什麼嗎?

回答

11

只有5倍快?你讓我感到驚訝。據推測,這意味着你的樣本數據中沒有很多零。

異常比簡單比較更昂貴。如果使用正確(即在特殊情況下),它們不會顯着影響性能 - 因爲如果您拋出足夠的例外來產生重大影響,那麼您的服務可能已經洗腦。它確實當您使用異常來嘗試忽略您可以非常容易地測試的條件時會導致問題 - 就像這個。

有一件事要注意異常的成本:在調試器中的成本比沒有附加調試器的情況下要多得多;特別是需要加載一堆資源的第一個異常可能需要幾秒而不是微/毫秒。如果您打算對代碼進行基準測試,那麼不要在調試器中這樣做 - 這在一般情況下是正確的,但對於異常情況尤其如此。

10

因爲異常是昂貴的。

當引發異常時,運行時需要挑出相當多的信息(例如堆棧跟蹤)並將其提升。這需要時間和資源,當比較測試0值非常便宜時。

請參閱this SO question詢問有多少信息需要特殊例外。

5

錯誤,因爲異常比檢查慢。例外情況通常有很多基礎設施,簡單的if聲明沒有。

它們不是等效的操作,因爲即使您選擇不使用,也會發生異常中的大量信息。

3

爲什麼例外很慢?

因爲當引發和捕獲異常時會發生很多事情。有關詳細信息,請參閱Chris Brumme's post about the managed exception modelthis post about the underlying Win32 SEH model

爲什麼簡單的測試很快?

因爲它只是執行一條跳轉指令,這取決於兩個整數的比較結果,它比異常工作少得多。

這是否意味着我應該總是嘗試避免異常?

不,它取決於語義。如果用零除是一個真正的異常情況,你不希望發生,並且你的程序不能合理處理,那麼讓異常發生並使程序崩潰。但是,如果這是一個預期的情況,並且您可以合理的方式處理,那麼避免這種例外似乎是合理的。

1

例外是極其緩慢 - 這是.net框架具有的TryParse方法的原因:

// This is much quicker... 
double result; 
if (!double.TryParse("Twelve", out result)) 
{ 
    result = -1; 
} 
return result; 

// Than this... 
try 
{ 
    return double.Parse("Twelve"); 
} 
catch 
{ 
    return -1; 
} 

你應該總是嘗試和避免例外(除非在特殊情況下 - 哈哈...)