Reputation: 4626
There has been asked that question already. The answer was "Stack space for local variables is usually allocated in function scope." and so there is no difference in overhead in declaring variables outside/inside of a loop.
Now, imagine that we have a snippet with a function inside of the loop:
void do_sth(int &i) {int var=i+1;}
int i = 0;
while(i < 100)
{
do_sth(i);
i++;
}
And a second snippet with a variable declared outside:
int i = 0;
int var;
while(i < 100)
{
var = i+1;
i++;
}
My question is - what is the overhead in case of the first snippet in a practical scenario (with a modern compiler)? If indeed there is an overhead, then how big is it? Is it comparable with, say, doing extra addition (operator+) on integers in each step of the loop?
Upvotes: -1
Views: 302
Reputation: 40659
What I would want to know is - what percent of the overall program's execution time is spent within this loop?
For example, if this is only a test program, and you're executing that code 1e9 times and timing it, and doing nothing else, then it will make a significant difference if the function call is inlined or not.
In any realistic program in my experience, it's very rare for such a loop to be taking much percent of the time. I assume you don't need to be told this, but some programmers have to learn a sense of proportion. Getting a haircut won't help one lose weight.
Upvotes: 0
Reputation: 1420
Are you sure you've framed the problem/question correctly ? From what you have posted - the do_sth function will have the usual function call overhead. If you inline it that overhead will go away.
Upvotes: 0
Reputation: 20191
I'm assuming that the compiler is allowed to optimise the code to the best of it's ability (otherwise talking about performance is somewhat pointless).
If the body of do_sth
is visible when compiling the loop in your example, the compiler will most likely inline it and then remove the assignment to var
(and allocation of stackspace for var
) as dead code, so for this scenario the overhead is not really existing. If do_sth
can't be inlined, the cost of the function call is more of a concern then the declaration of an int. And in case the function can be inlined there is a distinct possiblitiy of the compiler transforming the first version into the second one even if var
isn't dead code. So for examples like this it really won't matter.
It can matter, if your variable is a more complex type (a non POD classtype). In that case the first version will call the constructor and destructor once for each iteration, while the second will call the assignment operator once for each iteration and constructor and destructor only once. Note however that this doesn't say anything about which version is faster (depends on the implementation of those methods).
Upvotes: 0
Reputation: 1923
The best way to find out is to look at the disassemly code in debugger. In this case first code has the overhead of a function call in the loop. Depending on calling convention used for the function different things can happen for a function call. The usual scenario in assembly code is pushing the argument to the stack, calling the function, then function creates a stack frame, pops the stack to get the parameter, and on function return, popping the stack to get the callers caller's stack frame. For This code which function body is very short, the over head can be around 10 times of the actual function body. (10 instructions vs. 1 instruction). If you define the function as inline function, all the overhead goes away.
Upvotes: 0
Reputation: 96109
int i = 0;
int var;
while(i < 100)
{
var = i+1;
i++;
}
int i = 0;
while(i < 100)
{
int var = i+1;
i++;
}
Will generally produce exactly the same code. There are however good reasons to use the second.
It's intent is clearer and the code may be optomised better since the compiler knows that var is only required for the duration of the loop
Upvotes: 0
Reputation: 2051
Current compilers are smart enough to check the usage of variables and functions, and optimize the code at both compile time and link time. Hence there should be negligible difference between the two pieces of code, after optimizations. This LLVM Link time optimization document should provide a better insight regarding the same.
Upvotes: 0
Reputation: 98348
A modern compiler, with optimizations enabled, will most likely inline the function call, provided it complies with the inline requirements (no external linkage, etc.), and so the two versions will generate identical code.
If the function is not inlined, then there is indeed an overhead: a function call and a function return, with the argument passed in the stack. That is a bit more than a simple addition.
Upvotes: 1
Reputation: 81684
Any reasonable compiler, if asked to optimize the code at even the most basic level, would generate exactly the same instructions for the two snippets.
Upvotes: 1