2010-08-08 222 views
0

我正在寫一個有趣的程序,並且每次演奏都對我來說非常痛苦。 所以我想知道什麼更好 - 做一個額外的「if」語句來減少一些函數調用,或者避免那些「如果」和更多funciton調用。該函數是虛方法,它覆蓋IEqualityComparer的方法Equals,它只是比較兩個文件的大小和散列值。 if語句比較這兩個文件的大小。我認爲你有這個邏輯的重點。你可以看到我正在用C#編寫這個程序。所以也許任何人都可以回答我,因爲這不是我第一次想知道要選什麼。感謝速度更快 - if語句還是函數的調用?

+4

沒有代碼,你的問題非常模糊。即使有了代碼,我仍然期望在不知道實際情況的情況下仍然有點模糊。 – 2010-08-08 17:42:44

+0

'關閉不是一個真正的問題'?真的嗎? *卷眼睛* – 2010-08-08 19:11:41

回答

0

我的猜測是,如果一個語句是更好的,但與當今先進的編譯器,你永遠不能告訴。你最好的選擇是嘗試兩種方式並比較性能。

3

您是否嘗試過分析找出?你確定這些中的任何一個是你應用程序中的瓶頸嗎?

+0

當然沒有。在我看來,這些時刻更是瓶頸。一切安好。我無法決定選擇什麼。 分析工作非常巧妙。當我比較目錄中的所有文件和它的子目錄時,即使我改變了很多東西,也比下次它做同樣的工作快40倍。所以我不能比較相同文件夾的結果=( – Mark 2010-08-08 18:39:18

+3

@Mark:如果你不知道它是否會產生任何影響,這種決定是毫無意義的! – 2010-08-08 18:51:33

1

在過去的486和更舊的日子裏,當CPU處於「啞」狀態時,分支邏輯(例如if())會導致管道和/或緩存刷新,這會降低速度。現在,隨着現代編譯器和無序分支機構預測爲您洗碗碟機的CPU,這種開銷很小。

的唯一正確的方法回答你的問題是:基準這兩種方法,看看這是更快。

1

是由你觀察到在測試或只是一個事實,即你想想浪費了幾個週期的可能性實際性能的痛苦?如果是第二種情況,解決問題的唯一有效方法就是通過工作態度。

分支機構的成本是很難預測的,因爲現代處理器使用一些非常聰明的技術,以加速執行。它們存儲一些用於預測分支目標的特殊數據結構。如果預測是正確的,那麼這個分支很便宜,否則就很昂貴。錯誤預測的比率很低,但當然不是零。我不認爲你可以得到一個明確的答覆你的問題

8
  1. 如果你真的需要這麼多的表現如此糟糕,你爲什麼不採用匯編語言編程?

  2. 如果您仍然確定您確實需要擔心這個問題,請首先檢查其他優化機會,這些優化機會有更大的潛力(更好的算法可能會使數量級比任何微優化更差)。

  3. 如果優化生活狗屎了一切的,可以肯定的唯一方式是個人資料。真。無論我們中的任何人試圖猜測,他們都可能會低估JIT。

  4. 不過我對這個意見:一般來說,分支預測錯誤可能會傷害遠不止一個函數調用,因爲它螺絲緩存。但是誰說它會編譯成可能會導致緩存的代碼?編輯:但是,因爲它看起來像是比較文件內容的嚴格相等性,所以在長度不同的情況下短路可以節省很多時間(考慮:文件系統告訴你這個長度需要多長時間?知道,幾乎沒有。需要多長時間散列10 MB文件?很長,n比較)。所以如果我猜對了,那就去短路,大聲喊叫。

+0

好的,我明白了你的觀點。不是在優化程序,而是爲了知道答案,因爲「這不是我第一次想知道該選什麼」 – Mark 2010-08-08 18:28:46

+0

如果你看到了這個觀點,那麼答案是:在最清晰的代碼中做什麼結果並表達程序的邏輯最好;-) – delnan 2010-08-08 19:21:34

0

沒有分析就很難知道。但無論哪種方式,我都可以告訴你,你的算法通常比if vs function重要得多,而通過function通常可以更容易,更快速,更安全地更換和更新實現。最終要做更多的工作來改進算法中更重要的部分。而且,再次,知道你在那裏做的方式是簡介

+0

好的,謝謝你們。我得到了我正在尋找的答案 - 「現在人們可以真正告訴我」。這真的是我期待聽到的。所以謝謝。 – Mark 2010-08-08 18:31:16

0

答案取決於一兩件事:「我使用的是一個完全新空房禁地編譯」

既然你不是,答案是「沒關係」。編譯器和JIT'er大量轉換您的代碼,所以實際執行的內容與您編寫的代碼完全不同。

例如,函數調用可以內聯,消除函數調用的所有開銷。

因此:編寫易於理解的代碼,並且作爲一項附加功能,編譯器在優化代碼時也會變得更容易理解。

2

保留 - 如果 - 運行速度會更快。

很明顯,創建一個文件的哈希將花費相當多比if更多的時間。

0

if由於分支可能會產生成本。成本取決於在if情況下運行的代碼,在else情況下運行的代碼,CPU高速緩存的大小以及編譯器決策。

函數調用可能會因調用函數的代價而產生成本。這可能比if大得多,或者它可能爲零(因爲調用是內聯的 - 甚至當編譯器可以「看到」在編譯時將調用哪個窗體時虛擬調用也會發生內聯),或者它可以介於兩者之間。

因此,這個問題確實沒有一般的答案。即使你進行配置文件,也沒有什麼可以說,即使使用程序集的二進制副本(因爲抖動會不同),或者使用不同版本的.NET環境,在另一種架構上也不會有所不同(在此處「不同版本」包括服務包,熱修補程序和修補程序)。