Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the ranged based for loop beneficial to performance?

Reading various questions here on Stack Overflow about C++ iterators and performance**, I started wondering if for(auto& elem : container) gets "expanded" by the compiler into the best possible version? (Kind of like auto, which the compiler infers into the right type right away and is therefore never slower and sometimes faster).

** For example, does it matter if you write

for(iterator it = container.begin(), eit = container.end(); it != eit; ++it) 

or

for(iterator it = container.begin(); it != container.end(); ++it) 

for non-invalidating containers?

like image 619
TeaOverflow Avatar asked May 30 '12 18:05

TeaOverflow


People also ask

What is the purpose of the range for loop?

To loop through a set of code a specified number of times, we can use the range() function, The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.

What is a range-based loop?

Range-based for loop in C++ is added since C++ 11. It executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

Which is more efficient while loop or for loop?

Generally, the for loop can be more efficient than the while loop, but not always. The idea of the While loop is: While something is the case, do the following block of code. In this code, we have defined a variable name condition, and condition starts at a value of 1.

What is the difference between for range loop and?

The "for" loop For loops can iterate over a sequence of numbers using the "range" and "xrange" functions. The difference between range and xrange is that the range function returns a new list with numbers of that specified range, whereas xrange returns an iterator, which is more efficient.


2 Answers

The Standard is your friend, see [stmt.ranged]/1

For a range-based for statement of the form

for ( for-range-declaration : expression ) statement 

let range-init be equivalent to the expression surrounded by parentheses

( expression ) 

and for a range-based for statement of the form

for ( for-range-declaration : braced-init-list ) statement 

let range-init be equivalent to the braced-init-list. In each case, a range-based for statement is equivalent to

{   auto && __range = range-init;   for ( auto __begin = begin-expr,              __end = end-expr;         __begin != __end;         ++__begin )   {     for-range-declaration = *__begin;     statement   } } 

So yes, the Standard guarantees that the best possible form is achieved.

And for a number of containers, such as vector, it is undefined behavior to modify (insert/erase) them during this iteration.

like image 112
Matthieu M. Avatar answered Sep 23 '22 08:09

Matthieu M.


Range-for is as fast as possible since it caches the end iterator[citation provided], uses pre-increment and only dereferences the iterator once.

so if you tend to write:

for(iterator i = cont.begin(); i != cont.end(); i++) { /**/ } 

Then, yes, range-for may be slightly faster, since it's also easier to write there's no reason not to use it (when appropriate).

N.B. I said it's as fast as possible, it isn't however faster than possible. You can achieve the exact same performance if you write your manual loops carefully.

like image 32
Motti Avatar answered Sep 20 '22 08:09

Motti