2016-01-06 52 views
2

有時候爲了清晰起見,我在代碼中聲明瞭「一次使用」變量。這是否會顯着影響性能或者編譯器是否可以優化它?在C++中應該避免變量聲明嗎?

例如,我會傾向於做:

int minVal = long_arithmetic_expresion(); 
int maxVal = even_longer_expression(); 

for (int i = minVal; i < maxVal; i++) 
    { 
     // Do stuff not related to minVal or maxVal 
    } 

double part1 = 4*sqrt(something)* ... // Very long thing 
double part2 = 5*sqrt(something else)* ... // Very long thing 

double interestingValue = part1/part2; // This is the only interesting variable for later 

不是:

for (int i = long_arithmetic_expresion(); i < even_longer_expression(); i++) 
    { 
     // Do stuff not related to minVal or maxVal 
    } 

double interestingValue = (4*sqrt(whatever)* ...)/(5*sqrt(something else)* ...); 

for循環會被包含在將要多次調用函數,所以即使是很小的性能在我的情況下,收益將是相關的。

注:

因爲它很快就被指出,有一個機會,even_longer_expression()可以在循環,這當然是不好的每一步進行評估。 爲了清楚起見,我的問題涉及到聲明一次性變量的事實。 我在循環後添加了更多的代碼。我指的是變量part1part2

+0

在你的例子中'int maxVal = even_longer_expression();'只應該被聲明 – Evgeny

+3

'even_longer_expression()'將會被每次通過評估,所以當然不需要在那裏進行評估。 –

+1

如果可能,'minVal'和'maxVal'應該是'const'或者甚至'constexpr'。它不僅可以防止您意外更改其值,還可以提示編譯器進行更多優化。 –

回答

3

這是否會對性能產生顯着影響,或者編譯器是否可以對其進行優化?

完全取決於:

如果long_arithmetic_expresion()even_longer_expression()被標記爲constexpr,並不太可能在運行時改變,編譯器可以優化了重複這些函數的調用。

否則,最好使用一次初始化的變量。

+0

另外,將'maxVal'設爲'const'。那麼,這也是傳統上用迭代器結束時看到的風格。它可以輕鬆避免重複評估'for'循環的每次迭代。 – B98

+0

@ B98簡而言之,這是否意味着在聲明額外的變量時沒有性能損失,如果它們是'const',但是如果它們不是'const',避免額外的聲明可能會更好? – frischkase

+1

@frischkase取決於編譯器和開關,但是我認爲'const'可能會增加觸發優化的機會,而不是聲明一個變量並將許多代碼集中在一起,而是看起來過早的優化。如果需要的話,只有目標代碼會顯示實際的需求,但是今天的優化器確實遵循流程和優化.-'const'和一個變量都引入*名稱*,可以表達意圖或者簡寫const添加常量意義。我認爲在這種情況下,績效不是主要問題,邏輯和風格可能是。 – B98

1

除非你禁用優化,下面的代碼幾乎肯定會顯示出絕對的現代編譯器相同的性能(因爲表現明顯獨立):

// save to temporary minVal variable 
int minVal = long_arithmetic_expresion(); 
int maxVal = even_longer_expression(); 
for (int i = minVal; i < maxVal; i++) { 
    ... 
} 

// avoid creating temporary minVal variable 
int maxVal = even_longer_expression(); 
for (int i = long_arithmetic_expresion(); i < maxVal; i++) { 
    ... 
} 

但第一個版本是往往更具可讀性=)

原因是:copy propagation對於基本類型的變量而言對於編譯器來說是微不足道的。所以在第一個版本中編譯器會刪除i = minVal作業。