2013-05-09 53 views
3

我記得我看到的地方(大概在Github上)的一個例子是這樣的二傳手:是否有意義,以驗證是否值是一個二傳手不同

void MyClass::setValue(int newValue) 
{ 
    if (value != newValue) { 
     value = newValue; 
    } 
} 

對我來說並沒有賺很多的意義,但我想知道它是否會改善性能。

+6

對我來說,似乎表現可能會更糟糕。假設你的數據是正常分發的,你將在大部分時間做一個不必要的if-check。 – Porkbutts 2013-05-09 21:32:35

+1

後續問題,編譯器會優化這個'int'的情況嗎? – Inverse 2013-05-15 17:43:16

回答

4

指令流水線越深(至少在Intel平臺上越深),branch misprediction的成本就越高。

當某個分支出現錯誤預測時,錯誤預測的 路徑中的某些指令仍然在整個流水線中移動。這些 指令來執行所有的工作都浪費了,因爲他們不會被執行已經正確 分支預測

所以,是的,增加一個if詮釋他的代碼實際上可以影響性能。寫入將被L1緩存,可能很長一段時間。如果寫入必須可見,那麼該操作必須互鎖才能開始。

7

它對scalar types沒有任何意義,但它可能對某些user-defined類型有意義(因爲類型可能真的很「大」或其賦值運算符可以做一些「硬」工作)。

+0

如果用戶定義的類型是一個「l值引用」,那麼也是如此,但如果不是這樣,那麼你可能最好做一個動作(沒有檢查) – Duncan 2013-05-10 02:11:24

4

您可以真正說出的唯一方法是通過實際測試不同的替代方法(基準測試和/或分析代碼)。不同的編譯器,不同的處理器和不同的代碼調用它會產生很大的差異。一般來說,對於「簡單」數據類型(int,double,char,指針等),它是沒有意義的。它只會讓代碼變得更長,更復雜[至少如果編譯器按照你的要求去做 - 它可能會意識到,「這沒有任何意義,讓我們刪除這個檢查 - 我不會依賴於編譯器通常比你聰明,但編譯器的生活更加困難,幾乎不會導致更好的代碼]

編輯:另外,它只會使比較易於比較的東西變得很有意義。在它們相等的情況下比較數據是困難的(例如,如果長字符串相同(如果字符串開始相同,並且僅在最後幾個字符中不同),那麼長字符串會從兩個字符串中讀取大量讀取。所以很少有儲蓄,對於有一堆成員的班級也是如此,這些班級往往幾乎都是一樣的,但是有一兩個字段沒有,等等。另一方面,如果你有一個「客戶數據「類,其具有必須是唯一的整數客戶ID,然後僅比較客戶ID將是」便宜「,但是將客戶名稱,地址,電話號碼和其他數據複製到客戶將是昂貴。 [當然,在這種情況下,它爲什麼不是一個(智能)指針或引用?]。結束編輯。

如果數據在不同處理器(多線程訪問相同數據)之間「共享」,那麼它可能會有所幫助[特別是如果經常讀取這個值,並且通常用與以前相同的值編寫] 。這是因爲從其他處理器的緩存中「踢出」舊值是很昂貴的,而且如果你實際改變某些東西,你只想這樣做。

當然,當您正在編寫代碼時,只擔心性能問題,因爲您知道這些代碼絕對是性能熱路的最尖端。其他任何地方,儘可能使代碼易於閱讀並且儘可能簡潔明瞭始終是最佳選擇 - 這通常還會使編譯器更有能力確定實際正在進行的操作並確保獲得最佳優化結果。

2

這種模式在Qt中很常見,其中API高度依據signals & slots。這種模式有助於避免循環連接中的無限循環。

就你的情況而言,如果信號不存在,這個代碼只會殺死性能,正如@ remus-rusanu和@ mats-petersson所指出的那樣。

相關問題