Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


@Andrew Grant: Why. Assignment operator is usually defined as copy construct into tmp followed by swap (to be exception safe) followed by destroy tmp. Thus assignment operator is not that different to construction/destroy cycle above. See stackoverflow.com/questions/255612/ for example of typical assignment operator.

Correct idea wrong reason. Variable outside the loop. Constructed once, destroyed once but asignment operator applied every iteration. Variable inside the loop. Constructe/Desatructor aplied every iteration but zero assignment operations.

For non-POD class types that have non-trivial constructors, it WILL make a difference -- in that case, putting the variable outside the loop will only call the constructor and destructor once and the assignment operator each iteration, whereas putting it inside the loop will call the constructor and destructor for every iteration of the loop. Depending on what the class' constructor, destructor, and assignment operator do, this may or may not be desirable.

For primitive types and POD types, it makes no difference. The compiler will allocate the stack space for the variable at the beginning of the function and deallocate it when the function returns in both cases.

If construct/destruct are expensive, their total cost is a reasonable upper limit on the cost of the operator=. But the assignment could indeed be cheaper. Also, as we expand this discussion from ints to C++ types, one could generalize 'var=4' as some other operation than 'assign variable from a value of the same type'.

It is true if the loop body does the assignment anyway, not just for initialization. And if there's just a body-independent/constant initialization, the optimizer can hoist it.

This is the best answer but these comments are confusing. There's a big difference between calling a constructor and an assignment operator.

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


@Mehrdad Afshari a variable in a loop gets its constructor called once per iteration. EDIT - I see you mentioned this below, but I think it deserves mention in the accepted answer as well.

@toto A variable like this could also be nowhere the var variable is initialized but never used, so a reasonable optimiser can just remove it completely (except the second snippet if the variable was used somewhere after the loop).

Are you sure you should be talking about stack space right away. A variable like this could also be in a register.

I wish those guys who teach at out college at least knew this basic thing. Once he laughed at me declaring a variable inside a loop and I was wondering what's wrong until he cited performance as the reason not to do so and I was like "WTF!?".

Stack space for local variables is usually allocated in function scope. So no stack pointer adjustment happens inside the loop, just assigning 4 to var. Therefore these two snippets have the same overhead.

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


LockMgr lock( myCriticalSection);
while (i< 100) {

    // do stuff...

}
while (i< 100) {
    LockMgr lock( myCriticalSection); // acquires a critical section at start of
                                      //    each loop iteration

    // do stuff...

}   // critical section is released at end of each loop iteration

An RAII class might need this behavior. For example, a class that manages file access lifetime might need to be created and destroyed on each loop iteration to manage the file access properly.

For a built-in type there will likely be no difference between the 2 styles (probably right down to the generated code).

However, if the variable is a class with a non-trivial constructor/destructor there could well be a major difference in runtime cost. I'd generally scope the variable to inside the loop (to keep the scope as small as possible), but if that turns out to have a perf impact I'd look to moving the class variable outside the loop's scope. However, doing that needs some additional analysis as the semantics of the ode path may change, so this can only be done if the sematics permit it.

Suppose you have a LockMgr class that acquires a critical section when it's constructed and releases it when destroyed:

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


LockMgr lock( myCriticalSection);
while (i< 100) {

    // do stuff...

}
while (i< 100) {
    LockMgr lock( myCriticalSection); // acquires a critical section at start of
                                      //    each loop iteration

    // do stuff...

}   // critical section is released at end of each loop iteration

An RAII class might need this behavior. For example, a class that manages file access lifetime might need to be created and destroyed on each loop iteration to manage the file access properly.

For a built-in type there will likely be no difference between the 2 styles (probably right down to the generated code).

However, if the variable is a class with a non-trivial constructor/destructor there could well be a major difference in runtime cost. I'd generally scope the variable to inside the loop (to keep the scope as small as possible), but if that turns out to have a perf impact I'd look to moving the class variable outside the loop's scope. However, doing that needs some additional analysis as the semantics of the ode path may change, so this can only be done if the sematics permit it.

Suppose you have a LockMgr class that acquires a critical section when it's constructed and releases it when destroyed:

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


I once ran some perfomance tests, and to my surprise, found that case 1 was actually faster! I suppose this may be because declaring the variable inside the loop reduces its scope, so it gets free'd earlier. However, that was a long time ago, on a very old compiler. Im sure modern compilers do a better job of optimizing away the diferences, but it still doesn't hurt to keep your variable scope as short as possible.

Please post your setup and results.

The difference comes probably from the difference in scope. The smaller the scope the more likely the compiler is able to eliminate serialization of the variable. In the small loop scope, the variable was likely put in a register and not saved on the stack frame. If you call a function in the loop, or dereference a pointer the compiler doesn't really know where it points to, it will spill the loop variable if it is in function scope (the pointer might contain &i).

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


Ah yes, I forgot to address space efficiency - that's ok - 2 ints for both. It just seems odd to me that programmers are missing the forest for the tree -- all these suggestions about some code that doesn't terminate.

Both loops have the same efficiency. They will both take an infinite amount of time :) It may be a good idea to increment i inside the loops.

It's OK if they don't terminate. Neither one of them is called. :-)

Yes, stack overflow is always the most correct answer!

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


@Andrew Grant: Why. Assignment operator is usually defined as copy construct into tmp followed by swap (to be exception safe) followed by destroy tmp. Thus assignment operator is not that different to construction/destroy cycle above. See stackoverflow.com/questions/255612/ for example of typical assignment operator.

Correct idea wrong reason. Variable outside the loop. Constructed once, destroyed once but asignment operator applied every iteration. Variable inside the loop. Constructe/Desatructor aplied every iteration but zero assignment operations.

For non-POD class types that have non-trivial constructors, it WILL make a difference -- in that case, putting the variable outside the loop will only call the constructor and destructor once and the assignment operator each iteration, whereas putting it inside the loop will call the constructor and destructor for every iteration of the loop. Depending on what the class' constructor, destructor, and assignment operator do, this may or may not be desirable.

For primitive types and POD types, it makes no difference. The compiler will allocate the stack space for the variable at the beginning of the function and deallocate it when the function returns in both cases.

If construct/destruct are expensive, their total cost is a reasonable upper limit on the cost of the operator=. But the assignment could indeed be cheaper. Also, as we expand this discussion from ints to C++ types, one could generalize 'var=4' as some other operation than 'assign variable from a value of the same type'.

It is true if the loop body does the assignment anyway, not just for initialization. And if there's just a body-independent/constant initialization, the optimizer can hoist it.

This is the best answer but these comments are confusing. There's a big difference between calling a constructor and an assignment operator.

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


subl    $24, %esp
L3:
        movl    $4, -12(%ebp)
L2:
        cmpl    $99, -16(%ebp)
        jle     L3
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    $0, -16(%ebp)
        jmp     L2
L3:
        movl    $4, -12(%ebp)
L2:
        cmpl    $99, -16(%ebp)
        jle     L3
        leave
        ret
_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    movl    $0, -16(%ebp)
    jmp L2
L3:
    movl    $4, -12(%ebp)
L2:
    cmpl    $99, -16(%ebp)
    jle L3
    leave
    ret
main() { while(int i < 100) { int var = 4; } }
main(){ int var; while(int i < 100) { var = 4; } }

"Which is about as efficient as you can be without removing the loop entirely" Not quite. Partially unrolling the loop (doing it say 4 times per pass) would speed it up dramatically. There are probably many other ways to optimize... although most modern compilers would probably realize that there's no point in looping at all. If 'i' was used later, it'd simply set 'i' = 100.

And finally the only thing in the loop is the assignment and condition check:

As was the Original Post!

From these, you can see two things: firstly, the code is the same in both.

I actually produced the results by generating the machine code for each version. No need to run it.

I like answers that back the theory with proof! Nice to see ASM dump backing up the theory of being equal codes. +1

Look at what the compiler (gcc 4.0) does to your simple examples:

Secondly, the storage for var is allocated outside the loop:

They are both the same, and here's how you can find out, by looking at what the compiler does (even without optimisation set to high):

Which is about as efficient as you can be without removing the loop entirely.

that's assuming the code changed to incremented 'i' at all... as is it's just a forever loop.

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


EDIT: This answer is mostly obsolete now. With the rise of post-classical compilers, the cases where the compiler can't figure it out are getting rare. I can still construct them but most people would classify the construction as bad code.

I doubt it will affect optimization -- if the compiler performs any sort of data flow analysis, it can figure out that it's not being modified outside the loop, so it should produce the same optimized code in both cases.

It won't figure it out if you have two different loops using the same temp variable name though.

These days it is better to declare it inside the loop unless it is a constant as the compiler will be able to better optimize the code (reducing variable scope).

Note
Rectangle 27 0

Is there any overhead to declaring a variable within a loop (C++)?


I once ran some perfomance tests, and to my surprise, found that case 1 was actually faster! I suppose this may be because declaring the variable inside the loop reduces its scope, so it gets free'd earlier. However, that was a long time ago, on a very old compiler. Im sure modern compilers do a better job of optimizing away the diferences, but it still doesn't hurt to keep your variable scope as short as possible.

Please post your setup and results.

The difference comes probably from the difference in scope. The smaller the scope the more likely the compiler is able to eliminate serialization of the variable. In the small loop scope, the variable was likely put in a register and not saved on the stack frame. If you call a function in the loop, or dereference a pointer the compiler doesn't really know where it points to, it will spill the loop variable if it is in function scope (the pointer might contain &i).

Note