2011-10-08 94 views
4

所以我對它的c#方面感興趣 - 但我標記C++,因爲概念存在那裏,我沒有在'最後'關鍵字。 因此,無論如何 - 有沒有任何基準在線有關try-catch如何放慢速度或使用比簡單的'if-else'或其他代碼更多的內存?舉例來說,我現在正在寫代碼和使用的StreamWriter這表明7條可能的例外,當你在它按住鼠標...所以會有人聲稱,這將是更快,如果我寫的東西,如:trycatch如何傷害內存/ CPU?

////////////// 
if(path is not too long) 
{ if(file exists) 
{ if(nothing else uses the file) 
{ if(user is authorized) 
}}} 
//////////// 

你有7個條件,你可以使用,而不只是嘗試趕上 - 更不用說這些條件不能簡化爲單個if語句。

10x!

+1

不要只因爲你可以標記它。 – Puppy

+1

建議關閉如下副本: C#中的異常代價有多高? 使用異常拋出C#。它會影響性能嗎? 也可在以下網址獲得:http://msdn.microsoft.com/en-us/library/ms229009.aspx http://www.codeproject.com/KB/exception/ExceptionPerformance.aspx – holtavolt

+0

ps:是的,不僅僅是.net C++。 – nick

回答

6

try/catch如果發生異常,會有輕微的性能成本,但與文件訪問相比成本不值得擔心。

更重要的是,try/catch是正確的,嵌套的ifs不是,因爲文件系統是一個可以異步修改的共享資源。處理實際打開文件的錯誤或異常結果是避免競爭條件的唯一方法。

這些例子都使用的文件,但這裏有一個總的原則共享資源。

+0

+1用於指出競爭條件 –

1

任何性能差異都不是重點。

在打開文件之前測試某個文件是否存在,並不能保證另一個線程或進程沒有刪除或鎖定該文件;無論你是否成功,你只知道試圖打開它。因此OS調用通常會返回成功或失敗代碼,或者返回一個已知值來指示無效的文件句柄。

在面向對象的環境中,使用創建對象的習慣用法獲取資源(RAII)更清晰,那麼您必須拋出異常而不是允許創建無效對象。或者,你可以有一個面向對象的操作系統接口,它返回一個對已知不良對象的引用(例如null),但是你將這個異常延遲到程序的後面一點,所以可能不知道哪個文件無法打開。

另一個優點是,它允許庫提供對象來決定其有效性的條件是什麼 - 如果該文件實際上是指向WebDav服務器的鏈接,則表示其他條件,例如存在有效的網絡接口將是必需的。通過讓庫處理這些條件,實現細節對客戶端代碼隱藏起來(這適用於庫API作爲try/catch)

+1

通常情況下,最好的成語是tryIt/doIt模式,在「tryDoSomething」和「DoSomething」兩種形式中存在許多方法。例如,如果方法「OpenWuzzleFile」無法按預期打開文件,則會引發異常,而對於許多類型的錯誤,「TryOpenWuzzleFile」方法將返回錯誤代碼而不是拋出異常。如果預計方法「DoSomething」的用戶可能會在try/catch塊中自己插入一個DoSomething調用,那麼這個方法應該支持「TryDoSomething」變體。 – supercat

0

對於關於異常處理及其後果的真正精彩的討論,系統穩定性等)。我推薦閱讀第20章偉大的工作「通過C#的CLR」傑弗裏·裏希特。它肯定會回答你的大部分問題,並幫助理解.NET框架如何在底層處理異常,以及如何使用性能計數器作爲評估代碼拋出異常的影響的手段。

使用Guard子句(如您在問題中提到的)不是異常處理的替代方案,它們是兩個互補的概念。諸如if(file exists)之類的警戒條件可能會縮短其餘條件併產生更好的性能,因爲您的代碼可能不需要測試以下條件,即if(user is authorized)可能是資源密集型或耗時的。