2013-05-13 92 views

回答

10

在關心哪一個更快之前,您應該關心哪一個在語義上是正確的。如果你不需要改變被迭代的元素,你應該選擇第一個版本。否則,你應該選擇第二個版本。

當然,你可以反對,即使你不需要改變向量的內容,還有用來const參考選項:

for(auto const& value : ints) 

接下來的問題是和:哪個更快?通過參考const或值

好了,您還是應該先考慮是否以上的語義正確可言,這取決於你的for循環內做什麼:

int i = 0; 
for (auto const& x : v) // Is this correct? Depends! (see the loop body) 
{ 
    v[i] = 42 + (++i); 
    std::cout << x; 
} 

這就是說,對於基本類型,我會去與for (auto i : x)只要這在語義上是正確的。

我不認爲性能會變差(相反,我認爲它會更好),但是一如既往,在性能方面,備份假設的唯一有意義的方法是衡量,測量和測量。

5

如果修改value,並期望它來修改你矢量需要auto&一個實際的元素。如果你不修改value它可能編譯成與autoauto&完全相同的代碼(可以自行查找)。

我沒有使用基於QueryPerformanceCounter的定時器VS2012一些時間......

m::HighResTimer timer; 

    std::vector<int> ints(100000000, 17); 

    int count = 0; 

    timer.Start(); 
    for(auto& i : ints) 
     count += i; 
    timer.Stop(); 

    std::cout << "Count: " << count << '\n' 
       << "auto& time: " << duration_cast<duration<double, std::milli>>(timer.Elapsed()).count() << '\n'; 

    count = 0; 
    timer.Reset(); 
    timer.Start(); 
    for(const auto& i : ints) 
     count += i; 
    timer.Stop(); 

    std::cout << "Count: " << count << '\n' 
       << "const auto& time: " << duration_cast<duration<double, std::milli>>(timer.Elapsed()).count() << '\n'; 

    count = 0; 
    timer.Reset(); 
    timer.Start(); 
    for(auto i : ints) 
     count += i; 
    timer.Stop(); 

    std::cout << "Count: " << count << '\n' 
       << "auto time: " << duration_cast<duration<double, std::milli>>(timer.Elapsed()).count() << '\n'; 

結果....

Count: 1700000000 
auto& time: 77.0204 

Count: 1700000000 
const auto& time: 77.0648 

Count: 1700000000 
auto time: 77.5819 
Press any key to continue . . . 

我不會讀入的時間差在這裏。出於所有實際目的,它們是相同的,並且稍微波動地運行。

2

首先,如果您要修改價值使用auto&,如果不是 - 不要。因爲你可以不小心改變它。

但在const auto&和簡單的auto之間可能有選擇。我相信這裏的表現不是問題,對於std::vector<int>

爲什麼要用auto

  1. 它更容易閱讀
  2. 它允許改變(不改變vector

爲什麼要用const auto&

  1. 應該與其他類型的使用,所以它更通用的寫這種方式。此外,如果您將類型更改爲任何複雜類型,則不會意外獲得性能問題。
  2. 它不允許更改此變量的值,因此可能會在編譯時捕獲一些錯誤。

在這兩種情況下,你都應該明白你在做什麼。這可能取決於循環以某種方式修改我們的範圍。

2

在GCC中,兩個版本都使用優化標記-O1-O3編譯爲相同的程序集。

由於編譯器負責爲您優化,所以無論何時不需要更改值,我都會使用for (auto value : ints)。正如Andy指出的那樣,你可以使用const-refs,但如果沒有任何性能增益,那麼我就不會打擾。