| | |
Loop initialization question
Please support our C++ advertiser: Intel Parallel Studio Home
Thread Solved |
Is there a difference, in terms of performance, between the two loops below? (myvec is type
std::vector<int> .) C++ Syntax (Toggle Plain Text)
std::vector<int>::const_iterator pos; for (int i = 0; i < N; i++) { pos = myvec.begin(); // do something with pos }
C++ Syntax (Toggle Plain Text)
for (int i = 0; i < N; i++) { std::vector<int>::const_iterator pos = myvec.begin(); // do something with pos }
>Is there a difference, in terms of performance, between the two loops below?
It depends on your compiler. There are tons of factors that come into play, such as how your compiler manages stack space, whether the underlying type of const_iterator is a simple pointer or an object, how temporary objects are managed, whether object creation/destruction outweighs copy construction/assignment or the creation/destruction is a bottleneck, etc...
The best answer is that if it matters you'll notice a problem during performance profiling, and until then you should limit the scope of variables as much as possible. Thus, the second example is preferred.
It depends on your compiler. There are tons of factors that come into play, such as how your compiler manages stack space, whether the underlying type of const_iterator is a simple pointer or an object, how temporary objects are managed, whether object creation/destruction outweighs copy construction/assignment or the creation/destruction is a bottleneck, etc...
The best answer is that if it matters you'll notice a problem during performance profiling, and until then you should limit the scope of variables as much as possible. Thus, the second example is preferred.
I'm here to prove you wrong.
•
•
•
•
>Is there a difference, in terms of performance, between the two loops below?
It depends on your compiler. There are tons of factors that come into play, such as how your compiler manages stack space, whether the underlying type of const_iterator is a simple pointer or an object, how temporary objects are managed, whether object creation/destruction outweighs copy construction/assignment or the creation/destruction is a bottleneck, etc...
The best answer is that if it matters you'll notice a problem during performance profiling, and until then you should limit the scope of variables as much as possible. Thus, the second example is preferred.
Also to limit the scope of the variable and not create it every time we loop, couldn't we write:
c++ Syntax (Toggle Plain Text)
{ std::vector<int>::const_iterator pos; for (int i = 0; i < N; i++) { pos = myvec.begin(); // do something with pos } }
thanks in advance,
-nicolas
Two roads diverged in a wood, and I— I took the one less traveled by, and that has made all the difference.
by Robert Frost the "The Road Not Taken"
by Robert Frost the "The Road Not Taken"
>Narue could you elaborate more on this...
People usually have an easier time understanding the rough idea of memory when I explain it using assembly. When a "function" is called, local variables are typically allocated by adjusting the stack pointer to make a big enough gap to hold values for all of the variables:
That's the general idea behind figuring that the loop doesn't actually reallocate memory with each iteration. In that case, assuming that const_iterator is an class type rather than a built-in type, you can make the examples more accurate like so:
That seems like a big difference until you consider that the temporaries for myvec.begin() are probably going to be handled identically and that copy construction and assignment are similar enough not to be significantly different in their performance characteristics. Thus the only real difference is that the destructor is called for pos on every iteration in the second example. Unless the destructor is a heavy hitter when it comes to performance (note that the memory isn't being released at this point), the two examples won't much matter except for the scope issue.
That's the complicated situation, where const_iterator is a class type. If const_iterator is just a pointer, all of the construction and temporary crap doesn't even enter into the picture, and the two examples look like this (when you take the centralization of stack allocation into account):
Now there isn't any difference at all except for scope. And all of this is a direct analysis of the code without even considering compiler optimizations. When optimizations enter the picture, even basic logic can be tossed out the window.
However, guidelines exist so you don't have to be intimate with your compiler and to encourage good, portable code. And the guideline is to limit the scope of your variables as much as possible, and only optimize if performance becomes an issue and the scope of your variables turns out to be the bottleneck during profiling.
>It seems like an interesting subject!
It's very interesting, and it gets more interesting as you delve deeper and deeper.
>Also to limit the scope of the variable and not create it every time we loop, couldn't we write
Yup, and that's exactly how you'd create a C++ style for loop in C89:
People usually have an easier time understanding the rough idea of memory when I explain it using assembly. When a "function" is called, local variables are typically allocated by adjusting the stack pointer to make a big enough gap to hold values for all of the variables:
C++ Syntax (Toggle Plain Text)
function: add sp, localsize ; Make a hole ; Use the locals sub sp, localsize ; Close the hole ret
C++ Syntax (Toggle Plain Text)
std::vector<int>::const_iterator pos; for (int i = 0; i < N; i++) { pos = myvec.begin(); // do something with pos }
C++ Syntax (Toggle Plain Text)
{ std::vector<int>::const_iterator pos; for (int i = 0; i < N; i++) { pos.const_iterator ( myvec.begin() ); // do something with pos pos.~const_iterator(); } }
That's the complicated situation, where const_iterator is a class type. If const_iterator is just a pointer, all of the construction and temporary crap doesn't even enter into the picture, and the two examples look like this (when you take the centralization of stack allocation into account):
C++ Syntax (Toggle Plain Text)
std::vector<int>::const_iterator pos; for (int i = 0; i < N; i++) { pos = myvec.begin(); // do something with pos }
C++ Syntax (Toggle Plain Text)
{ std::vector<int>::const_iterator pos; for (int i = 0; i < N; i++) { pos = myvec.begin(); // do something with pos } }
However, guidelines exist so you don't have to be intimate with your compiler and to encourage good, portable code. And the guideline is to limit the scope of your variables as much as possible, and only optimize if performance becomes an issue and the scope of your variables turns out to be the bottleneck during profiling.
>It seems like an interesting subject!
It's very interesting, and it gets more interesting as you delve deeper and deeper.

>Also to limit the scope of the variable and not create it every time we loop, couldn't we write
Yup, and that's exactly how you'd create a C++ style for loop in C89:
c Syntax (Toggle Plain Text)
/* for ( int i = 0; i < N; i++ ) ; */ { int i; for ( i = 0; i < N; i++ ) ; }
I'm here to prove you wrong.
![]() |
Similar Threads
- finiding min in array till satisfies condition explained in prbm stmnt (C++)
- question on Stacks push,pop. (C++)
- C++ question on classes (C++)
- Pointers (C++)
Other Threads in the C++ Forum
- Previous Thread: Trying to draw green rectangle on Panel in Visual C++
- Next Thread: String input problem
| Thread Tools | Search this Thread |
api array arrays based beginner binary bitmap c++ c/c++ calculator char char* class classes coding compile compiler console conversion convert count data database delete desktop developer directshow dll dynamiccharacterarray email encryption error file forms fstream function functions game generator getline google graph homeworkhelper iamthwee ifstream input int integer java lib linkedlist linux list loop looping loops map math matrix memory multiple news node number numbertoword output parameter pointer problem program programming project proxy python random read recursion recursive reference return rpg sorting string strings struct template templates text tree unix url vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






