943,864 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Marked Solved
  • Views: 2997
  • C++ RSS
Jul 10th, 2008
0

Loop initialization question

Expand Post »
Is there a difference, in terms of performance, between the two loops below? (myvec is type std::vector<int> .)
C++ Syntax (Toggle Plain Text)
  1. std::vector<int>::const_iterator pos;
  2. for (int i = 0; i < N; i++) {
  3. pos = myvec.begin();
  4. // do something with pos
  5. }
C++ Syntax (Toggle Plain Text)
  1. for (int i = 0; i < N; i++) {
  2. std::vector<int>::const_iterator pos = myvec.begin();
  3. // do something with pos
  4. }
Similar Threads
Reputation Points: 68
Solved Threads: 4
Light Poster
titaniumdecoy is offline Offline
36 posts
since Mar 2007
Jul 10th, 2008
0

Re: Loop initialization question

in second you create std::vector<int>::const_iterator pos every time when you loop and then change value in first when loop it only change value
Last edited by ivailosp; Jul 10th, 2008 at 3:45 am.
Reputation Points: 21
Solved Threads: 22
Junior Poster
ivailosp is offline Offline
129 posts
since Apr 2008
Jul 10th, 2008
1

Re: Loop initialization question

>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.
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
Jul 10th, 2008
0

Re: Loop initialization question

Click to Expand / Collapse  Quote originally posted by Narue ...
>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.
Narue could you elaborate more on this... It seems like an interesting subject! Being ignorant in the beggining i would agree ivailosp , but you seem to have a point.

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)
  1. {
  2. std::vector<int>::const_iterator pos;
  3. for (int i = 0; i < N; i++)
  4. {
  5. pos = myvec.begin();
  6. // do something with pos
  7. }
  8. }

thanks in advance,
-nicolas
Reputation Points: 23
Solved Threads: 12
Posting Whiz in Training
n.aggel is offline Offline
202 posts
since Nov 2006
Jul 10th, 2008
4

Re: Loop initialization question

>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:
C++ Syntax (Toggle Plain Text)
  1. function:
  2. add sp, localsize ; Make a hole
  3.  
  4. ; Use the locals
  5.  
  6. sub sp, localsize ; Close the hole
  7. ret
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:
C++ Syntax (Toggle Plain Text)
  1. std::vector<int>::const_iterator pos;
  2. for (int i = 0; i < N; i++) {
  3. pos = myvec.begin();
  4. // do something with pos
  5. }
C++ Syntax (Toggle Plain Text)
  1. {
  2. std::vector<int>::const_iterator pos;
  3. for (int i = 0; i < N; i++) {
  4. pos.const_iterator ( myvec.begin() );
  5. // do something with pos
  6. pos.~const_iterator();
  7. }
  8. }
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):
C++ Syntax (Toggle Plain Text)
  1. std::vector<int>::const_iterator pos;
  2. for (int i = 0; i < N; i++) {
  3. pos = myvec.begin();
  4. // do something with pos
  5. }
C++ Syntax (Toggle Plain Text)
  1. {
  2. std::vector<int>::const_iterator pos;
  3. for (int i = 0; i < N; i++) {
  4. pos = myvec.begin();
  5. // do something with pos
  6. }
  7. }
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:
  1. /*
  2.   for ( int i = 0; i < N; i++ )
  3.   ;
  4. */
  5. {
  6. int i;
  7.  
  8. for ( i = 0; i < N; i++ )
  9. ;
  10. }
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: Trying to draw green rectangle on Panel in Visual C++
Next Thread in C++ Forum Timeline: String input problem





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC