遊戲引擎微優化情況:我正在使用C++ 11範圍for循環遍歷vector<int>
和auto
關鍵字。通過矢量的Foreach範圍迭代<int> - auto或auto&?
什麼是快:
for(auto value : ints) ...
或
for(auto& value : ints) ...
?
遊戲引擎微優化情況:我正在使用C++ 11範圍for循環遍歷vector<int>
和auto
關鍵字。通過矢量的Foreach範圍迭代<int> - auto或auto&?
什麼是快:
for(auto value : ints) ...
或
for(auto& value : ints) ...
?
在關心哪一個更快之前,您應該關心哪一個在語義上是正確的。如果你不需要改變被迭代的元素,你應該選擇第一個版本。否則,你應該選擇第二個版本。
當然,你可以反對,即使你不需要改變向量的內容,還有用來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)
只要這在語義上是正確的。
我不認爲性能會變差(相反,我認爲它會更好),但是一如既往,在性能方面,備份假設的唯一有意義的方法是衡量,測量和測量。
如果修改value
,並期望它來修改你矢量需要auto&
一個實際的元素。如果你不修改value
它可能編譯成與auto
或auto&
完全相同的代碼(可以自行查找)。
我沒有使用基於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 . . .
我不會讀入的時間差在這裏。出於所有實際目的,它們是相同的,並且稍微波動地運行。
首先,如果您要修改價值使用auto&
,如果不是 - 不要。因爲你可以不小心改變它。
但在const auto&
和簡單的auto
之間可能有選擇。我相信這裏的表現不是問題,對於std::vector<int>
。
爲什麼要用auto
vector
)爲什麼要用const auto&
在這兩種情況下,你都應該明白你在做什麼。這可能取決於循環以某種方式修改我們的範圍。
在GCC中,兩個版本都使用優化標記-O1
到-O3
編譯爲相同的程序集。
由於編譯器負責爲您優化,所以無論何時不需要更改值,我都會使用for (auto value : ints)
。正如Andy指出的那樣,你可以使用const-refs,但如果沒有任何性能增益,那麼我就不會打擾。