tags:

views:

284

answers:

9

Haven't used C++ in a while. I've been depending on my Java compiler to do optimization.

What's is the most optimized way to do a for loop in C++? Or it is all the same now with moderm compilers? In the 'old days' there was a difference.

for (int i=1; i<=100; i++)

OR

int i;
for (i=1; i<=100; i++)

OR

int i = 1;
for ( ; i<=100; i++)

Is it the same in C?

EDIT: Okay, so the overwhelming consensus is to use the first case and let the complier optimize with it if it want to.

+4  A: 

It's the same. The compiler will optimize these to the same thing.

Even if they weren't the same, the difference compared to the actual body of your loop would be negligible. You shouldn't worry about micro-optimizations like this. And you shouldn't make micro-optimizations unless you are performance profiling to see if it actually makes a difference.

Mark Byers
+10  A: 

I'd say that trivial things like this are probably optimized by the compiler, and you shouldn't worry about them. The first option is the most readable, so you should use that.

EDIT: Adding what other answers said, there is also the difference that if you declare the variable in the loop initializer, it will stop to exist after the loop ends.

Javier Badia
In regards to your edit, this depends on the compiler. I've seen at least one compiler (MSVC++6.0) where the variable does not cease to exist after the loop ends.
Jeff Barger
@Jeff Standard compliant compilers will restrict the scope of _i_ the for loop, but there are older compilers - like MSVC++ 6.0 - which don't. So, if you're using an older compiler, it's something to watch out for. Per the language standard, however, the scope is restricted to the for loop. Recent compilers should behave correctly in that regard.
Jonathan M Davis
On MSVC, the hack "#define for if(0) {} else for" could be used to get the correct behavior. Ah yes, the good old days...
Dan Olson
+5  A: 

I think all three ways are effecient equally.

Have you ever heard of premature optimization?

Messa
+2  A: 

It's the same in term of speed. Compiler will optimize if you do not have a later use of i.

In terms of style - I'd put the definition in the loop construct, as it reduces the risk that you'll conflict if you define another i later.

Uri
+7  A: 

The difference is scope.

for(int i = 1; i <= 100; ++i)

is generally preferable because then the scope of i is restricted to the for loop. If you declare it before the for loop, then it continues to exist after the for loop has finished and could clash with other variables. If you're only using it in the for loop, there's no reason to let it exist longer than that.

Jonathan M Davis
In some of the older compilers, the scope of i, is to the end of the function.moving the int, out of the loop keeps you good with other compilers.
EvilTeach
@EvilTech Only older, non-compliant compilers will have that problem. So, unless you think that there's a good chance that your code will be used with such a compiler, I wouldn't worry about it. If it is a problem, then putting an extra pair of braces around the for loop will fix the problem.
Jonathan M Davis
A: 

Don't worry about micro-optimizations, let the compiler do it. Pick whichever is most readable. Note that declaring a variable within a for initialization statement scopes the variable to the for statement (C++03 § 6.5.3 1), though the exact behavior of compilers may vary (some let you pick). If code outside the loop uses the variable, declare it outside the loop. If the variable is truly local to the loop, declare it in the initializer.

outis
A: 

It's all the same.

rmn
+1  A: 

It has already been mentioned that the main difference between the two is scope. Make sure you understand how your compiler handles the scope of an int declared as

for (int i = 1; ...;...)

I know that when using MSVC++6, i is still in scope outside the loop, just as if it were declared before the loop. This behavior is different from VS2005, and I'd have to check, but I think the last version of gcc that I used. In both of those compilers, that variable was only in scope inside the loop.

Jeff Barger
That's a well-known bug in VC++6. If you really care surround the for loop with another set of braces.
jmucchiello
+1  A: 

Let's say the original poster had a loop they really wanted optimized - every instruction counted. How can we figure out - empirically - the answer to his question?

gcc at least has a useful, if uncommonly used switch, '-S'. It dumps the assembly code version of the .c file and can be used to answer questions like the OP poses. I wrote a simple program:

int main( )
{
    int sum = 0;

    for(int i=1;i<=10;++i)
    {
        sum = sum + i;
    }
    return sum;
}

And ran: gcc -O0 -std=c99 -S main.c, creating the assembly version of the main program. Here's the contents of main.s (with some of the fluff removed):

    movl    $0, -8(%rbp)
    movl    $1, -4(%rbp)
    jmp     .L2
.L3:
    movl    -4(%rbp), %eax
    addl    %eax, -8(%rbp)
    addl    $1, -4(%rbp)
.L2:
    cmpl    $10, -4(%rbp)
    jle     .L3

You don't need to be an assembly expert to figure out what's going on. movl moves values, addl adds things, cmpl compares and jle stands for 'jump if less than', $ is for constants. It's loading 0 into something - that must be 'sum', 1 into something else - ah, 'i'! A jump to L2 where we do the compare to 10, jump to L3 to do the add. Fall through to L2 for the compare again. Neat! A for loop.

Change the program to:

int main( )
{
    int sum = 0;
    int i=1;
    for( ;i<=10;++i)
    {
        sum = sum + i;
    }
    return sum;
}

Rerun gcc and the resultant assembly will be very similar. There's some stuff going on with recording line numbers, so they won't be identical, but the assembly ends up being the same. Same result with the last case. So, even without optimization, the code's just about the same.

For fun, rerun gcc with '-O3' instead of '-O0' to enable optimization and look at the .s file.

main:
movl    $55, %eax
ret

gcc not only figured out we were doing a for loop, but also realized it was to be run a constant number of times did the loop for us at compile time, chucked out 'i' and 'sum' and hard coded the answer - 55! That's FAST - albeit a bit contrived.

Moral of the story? Spend your time on ensuring your code is clean and well designed. Code for readability and maintainability. The guys that live on mountain dew and cheetos are way smarter than us and have taken care of most of these simple optimization problems for us. Have fun!

Jesse K