向量<int>上的Foreach范围迭代 - auto或auto&?

Vit*_*meo 6 c++ performance foreach auto c++11

游戏引擎微优化情况:我正在使用C++ 11 range for循环来迭代a vector<int>,使用auto关键字.

什么是更快:

for(auto value : ints) ...
Run Code Online (Sandbox Code Playgroud)

要么

for(auto& value : ints) ...
Run Code Online (Sandbox Code Playgroud)

And*_*owl 13

在关心哪个更快之前,你应该关心哪个在语义上是正确的.如果您不需要更改正在迭代的元素,则应选择第一个版本.否则,您应该选择第二个版本.

当然,您可以反对即使您不需要更改向量的内容,仍然可以选择使用引用const:

 for(auto const& value : ints)
Run Code Online (Sandbox Code Playgroud)

然后问题变成:哪个更快?参考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;
}
Run Code Online (Sandbox Code Playgroud)

这就是说,对于基本类型,for (auto i : x)只要语义正确,我就会使用.

我不认为性能会更差(相反,我希望它会更好),但是在性能方面总是如此,支持您的假设的唯一有意义的方法是衡量,衡量和衡量.


Dav*_*vid 5

如果你修改value并期望它修改你需要 的向量中的实际元素auto&.如果你不修改value它可能编译成完全相同的代码与autoauto&(配置文件,以找出自己).

我使用VS2012和基于QueryPerformanceCounter的计时器进行了一些计时...

    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';
Run Code Online (Sandbox Code Playgroud)

结果....

Count: 1700000000
auto& time: 77.0204

Count: 1700000000
const auto& time: 77.0648

Count: 1700000000
auto time: 77.5819
Press any key to continue . . .
Run Code Online (Sandbox Code Playgroud)

我不会在这里读到时差.出于所有实际目的,它们是相同的,并且稍微波动以便运行.