2017-07-06 25 views
0

關於速度,如果我需要計算大量的表情,說:如何C++處理0 *(大表達式)

switch1*(large expression 1)+switch2*(large expression 2) 

根據我的投入,switch1可以01,因爲可以switch2是。對於C++來說,最快的做法是做出if語句還是像上面那樣寫下來?

+1

請提供一個[mcve],並且您可以在godbolt上檢查自己 –

+0

如果您的大型expresssion包含函數調用,其中編譯器無法確定它們沒有副作用,它們將不會被優化。如果任何一個開關在編譯時不是常量0值,也不會對整個表達式進行優化。 –

+5

看起來像過早的優化。首先測量,然後優化。 – Rakete1111

回答

0

所以,本質上則是問有關短路計算,你問C++是否會爲除了布爾表達式算術表達式。

這是很難證明一個否定的,但據我所知,C++只對邏輯表達式進行短路評估,因此沒有等價的算術表達式。另外,如果算術表達式是以短路方式進行評估的,我可以想象大量的代碼會破壞性很強,所以我認爲不會那樣。

0

理論上,編譯器可以生成代碼以避免計算表達式,如果它可以表明它沒有副作用。但在實踐中,不可能添加代碼來檢查值是否爲零,因爲它沒有理由認爲它是。

另一方面,邏輯運算(||&&)保證在C++中短路。所以你應該使用它們。

0
result = 0; 
if(switch1) { 
    result += large_expresion_1(); 
} 
if(switch2) 
    result += large_expression2(); 
} 

但是,如果你正在優化「大型表達式」一定要檢查是否實際上是更快地計算他們兩個,然後在網點的方式添加。例如像

result = ((-(uint64_t)(switch1)) & large_expression_1) + ((-(uint64_t)(switch2)) & large_expression_2); 

這樣bithacks一束這裏記載: https://graphics.stanford.edu/~seander/bithacks.html

基準和分離到,讀取生成的彙編語言找出編譯器實際上做的(或)您。

0

switch1可以01,一樣可以switch2

如果switch1switch2實際上只能有01值,那麼這將是更好地爲他們是布爾值,而不是整數。

布爾開關,你的說法就變成了:

result = (switch1 ? (large expression 1) : 0) 
     + (switch2 ? (large expression 2) : 0) 

正是在這種形式下,表現將即使其結果將不被使用計算的情況下。一個簡單而明確的方式,以避免浪費計算是明顯的:

result = 0; 
if(switch1) { 
    result += large expression 1; 
} 
if(switch2) { 
    result += large expression 2; 
} 

你可以通過提取方法,在其中傳遞的開關整理這件事:

result = guardedLargeExpression1(switch1, otherparams1) 
     + guardedLargeExpression2(switch2, otherparams2); 

... ..用。

int guardedLargeExpression1(bool switch, foo params) { 
    if(switch) { 
     return 0; 
    } 
    return large expression(...); 
} 

你也可以做聰明的東西與pointers to functions

int guardedFunctionCall(bool switch, int *functionptr(foo), foo arg) { 
    if(switch) { 
     return 0; 
    } 
    return (*functionptr)(arg); 
} 

...這是接近的那種你會用Java做的事情,當你使用Supplier懶洋洋地評估代碼。

或者,因爲你在C++不是C,你可以做更多的事情OO和實際使用的Supplier的C++相當於:What is the C++ equivalent of a java.util.function.Supplier?

0

如果依賴於精確的條件。 CPU,編譯器,確切的表達式。

如果if成爲彙編代碼中的條件跳轉,並且條件無法預測,則if可能會減慢程序速度。

如果條件不能被預測,並且「大表達式」其實很簡單,那麼做「乘法」可能會更快。但是,如果表達式計算速度慢,或者if可以完美分支預測(或者它不會編譯爲條件跳轉),那麼我認爲if方式會更快。

總之,你應該嘗試兩種解決方案,並檢查哪個更快。