2011-10-06 12 views
2

代碼類方法調用是否會在for循環中進行優化?

for (size_t i = 0; i < myClassObject.Method(); ++i) 
    some work; 

我想知道如果編譯器將優化出來的方法調用,並把它變成這樣?

size_t result = myClassObject.Method(); 
for (size_t i = 0; i < result; ++i 
    some work; 

如果它是一個函數調用,它會影響嗎?我擔心的是,我可能會對該方法進行1000次不需要的調用,但我更願意在條件中使用方法調用編寫它。

+0

類似的問題在這裏http://stackoverflow.com/questions/5607762/what-does-code-motion-mean-for-loop-invariant-code-motion – srikanta

+0

無所謂如果它是一個方法調用或純C風格的函數調用中,允許編譯器優化它的要求是相同的。 – Mat

+0

這是受廣泛實施的環路提升優化,又稱「環路不變代碼運動」。所以,是的。 http://en.wikipedia.org/wiki/Loop-invariant_code_motion –

回答

4

你應該在代碼中聲明你想要做什麼。如果你需要一筆款項,你就不會編寫代碼,而只是因爲你喜歡這樣做而增加代碼。它需要一個智能編譯器來實現對Method()的調用沒有副作用,並且主體的循環不會以任何方式直接或間接修改Method()中使用的參數。

我個人的偏好,爲了做我想做什麼,因爲我喜歡它寫出來,就是:

for (size_t i = 0, result = myClassObject.Method(); i < result; ++i) 
    some work; 
+0

我檢查了你的答案,所以你可以有你的威士忌晚上。謝謝@Kerrek也 – Mobius

4

這取決於編譯器是否能夠證明該調用的結果不可能改變循環體,所以不要依賴它。如果你想明確地提起,標準的寫法是這樣的:

for (std::size_t i = 0, end = myClassObject.Method(); i != end; ++i) 
{ 
    // ... 
} 

這同樣適用於基於迭代器的循環。

+0

我們通常與我們的答案一致,我們應該開始一個俱樂部! :P –

+0

@ K-ballo:我建議換檔,所以我可以有無SO威士忌的夜晚:-) –

1

通常,這將是不正確的優化,因爲該方法可能不會在每次調用時返回相同的結果。考慮它是否返回當前時間。

如果方法定義可在同一編譯單元(中包含的頭文件或同一個源文件)它的編譯器很簡單地告訴它總是返回相同的結果,那麼你可能得到這個優化。如果該方法被宣佈爲inline,我認爲這很可能。

我相信gcc至少現在有一些編譯標誌的模塊間優化,也可以跨源文件邊界做到這一點。不知道其他編譯器。