2013-07-07 22 views
6

考慮下面的代碼:優化器是否將臨時非POD類型移出循環?

while(is_running) 
{ 
    std::vector<buffer> buffers; 

    // fill buffers 

    // use buffers 
} 

是否現代編譯器執行以下轉型?

std::vector<bufer> buffers; 

while(is_running) 
{ 
    // fill buffers 

    // use buffers 

    buffers.clear(); 
} 
+0

爲什麼你認爲第二個會更高效?你有個人資料嗎? –

+1

@LuchianGrigore我能想到的唯一原因是第一個版本必須在每個循環中分配/解除分配,第二個版本不一定如此。 – juanchopanza

+0

@juanchopanza:正確的,第二個不會在每次循環迭代過程中不必要地分配/釋放。 – ronag

回答

4

明確知道的唯一方法就是測試,我會相當驚訝地看到一個優化進行這種優化。

甚至開始開展這種優化,編譯器必須:1)充分了解所涉及到「實現」(例如函數)operator newoperator delete的內部基本上反映任何其他的圖像,或2)它必須產生所有代碼對所有的內部函數(一路下跌至operator newoperator delete的調用,並有足夠的智慧,能夠推斷出從代碼相同的結論。

我幾乎無法想象第一個,但不記得曾經見過它。鑑於一個典型的堆管理者的複雜性,第二次罷工米真是令人難以置信。底線:我之前很驚訝,而且我相信我會再次 - 但會比大多數人感到更大的驚喜。

+2

此外,編譯器不得不擔心例如全局變量的副作用 - 包括例如「errno」。 –

0

我會驚訝地發現,編譯器實際上知道std容器,並在沒有我明確請求的情況下調用它們的方法。如果是這樣的話,想象一下,無論何時發佈新的庫模塊,編譯器的邏輯將如何增強!

不過,要找出一些C++編譯器確實具有標準庫的一些知識會很有趣。

編輯:好的,我找到了這樣的知識的一個例子:C++ 11基於範圍的for循環將std :: begin和std :: end應用到範圍。

無論如何,我們程序員必須真正理解我們編寫的代碼並找出優化方法。編譯器應該簡單地轉換我們的指令,只應用小的(但顯着的)優化(如內聯,複製等等)