Reputation: 93264
Game engine micro-optimization situation: I'm using C++11 range for loop to iterate over a vector<int>
, with the auto
keyword.
What is faster:
for(auto value : ints) ...
or
for(auto& value : ints) ...
?
Upvotes: 7
Views: 15471
Reputation: 8487
In GCC, both versions compile to the same assembly with optimization flags -O1
through -O3
.
Since the compiler takes care of the optimization for you, I would use the for (auto value : ints)
whenever you don't need to change the value. As Andy points out, you could use const-refs, but if there's no performance gain whatsoever, then I wouldn't bother.
Upvotes: 2
Reputation: 28178
If you modify value
and expect it to modify an actual element in the vector you need auto&
. If you don't modify value
it likely compiles into the exact same code with auto
or auto&
(profile it to find out for yourself).
I did some timing using VS2012 with a timer based on 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';
The Results....
Count: 1700000000
auto& time: 77.0204
Count: 1700000000
const auto& time: 77.0648
Count: 1700000000
auto time: 77.5819
Press any key to continue . . .
I wouldn't read into the time differences here. For all practical purposes they are identical, and fluctuate slightly run to run.
Upvotes: 5
Reputation: 47619
First of all, if you going to modify value use auto&
, if not - don't. Because you can accidentally change it.
But there may be choice between const auto&
and simple auto
. I believe that performance isn't issue here, for std::vector<int>
.
Why use auto
vector
)Why use const auto&
In both cases you should understand what do you do. It may depend if the cycle somehow modify our range.
Upvotes: 2
Reputation: 126422
Before caring about which is faster, you should care about which is semantically correct. If you do not need to alter the element being iterated, you should choose the first version. Otherwise, you should choose the second version.
Sure, you could object that even if you do not need to alter the content of the vector, there is still the option to use a reference to const
:
for(auto const& value : ints)
And then the question becomes: Which is faster? By reference to const
or by value?
Well, again, you should first consider whether the above is semantically correct at all, and that depends on what you are doing inside the for
loop:
int i = 0;
for (auto const& x : v) // Is this correct? Depends! (see the loop body)
{
v[i] = 42 + (++i);
std::cout << x;
}
This said, for fundamental types I would go with for (auto i : x)
whenever this is semantically correct.
I do not expect performance to be worse (rather, I expect it to be better), but as always when it comes to performance, the only meaningful way to back up your assumptions is to measure, measure, and measure.
Upvotes: 14