Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C++11 for loop allow new or better optimizations?

In C++11 we can now do :

void dosomething( std::vector<Thing>& things )
{
    for( Thing& thing : things )
    {
        dofoo( thing );
        wiizzz( thing );
        tadaa( thing );
    }

}

I know that the addition and use of lambda is syntactic sugar but it provide interesting optimization opportunities.

What about the for loop? Is it only syntactic sugar or can the compiler optimize some cases that it couldn't or would be too hard to do with handwritten loop?

like image 220
Klaim Avatar asked Oct 13 '10 15:10

Klaim


People also ask

How do compilers optimize for loops?

The compiler can do the following: create a separate version of the loop for each possible value of the variable operation . The transformation is called loop unswitching, because there is a different version of the loop for each value of the condition.

Are range based for loops faster?

Range-for is as fast as possible since it caches the end iterator[citationprovided], uses pre-increment and only dereferences the iterator once. 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).

Which loop is more efficient in C++?

Usually pre-increment / pre-decrement is faster than post-increment/post-decrement, because post-<> require to save a temporal value for returning.


2 Answers

It's just a syntactic sugar since the standard says that it's equivalent to a loop with iterators [ Edit: this means it doesn't provide any additional information to the compiler compared to the equivalent for loop — end edit ]. You may get a better performance though since it's equivalent to:

for(auto iter = con.begin(), end = con.end(); iter != end; ++iter)
{
    auto& ref = *iter;
    // ...
}

while most people may write:

for(auto iter = con.begin(); iter != con.end(); iter++)
{
    // use *iter directly
    // ...
}

which may be slower if the con.end(), iter++ or *iter are not trivial.

[ Edit:

lambda is syntactic sugar

Not really. Unlike for loop it allows the compiler to capture the stack-frame base pointer directly, for variables captured by reference this saves one address indirection per each use, compared to a handcrafted function object. — end edit ]

like image 126
Yakov Galka Avatar answered Oct 06 '22 01:10

Yakov Galka


Maybe, but probably not. It does eliminate the possible creating of an index/counter variable that won't be used. That's not required for a normal for loop either, but it's a lot more likely to happen just because it's what some people are accustomed to doing.

Realistically, it's unlikely to make any difference even from that though. I, at least, find it hard to imagine a compiler team so sophisticated that they have even the slightest aspiration toward supporting C++0x, that hasn't already handled the relatively trivial point of detecting and eliminating creating and incrementing a loop index that's never used.

like image 20
Jerry Coffin Avatar answered Oct 05 '22 23:10

Jerry Coffin