Thread: Postfix iterator increment faster than prefix?

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    1

    Postfix iterator increment faster than prefix?

    Hello guys,

    After performing some C++ testing on vector iterators. I have found that the postfix-increment is faster.

    Code:
    #include <vector>
    #include <stdlib.h>
    using namespace std;
    
    class TestClass {
    	int var1, var2;
    	float floatone;
    	public: inline TestClass() {}
    };
    
    #define USE_POSTFIX 1
    
    int main( int argc, char *argv[ ] ) {
    	vector<TestClass> vectorz( 10000 );
    	vector<TestClass>::iterator viterator;
    	volatile int garbage = 0;
    	for ( unsigned int i = 0; i < 10000; i += 1 ) {
    		for ( viterator = vectorz.begin(); viterator != vectorz.end();)
    		{
    			garbage += 1; // make sure optimizer doesn't balete the loop
    			#ifdef USE_POSTFIX
    				viterator++;
    			#else
    				++viterator;
    			#endif
    		}
    	}
    }
    Timings: Prefix 5.19s user time, Postfix 4.63s user time.

    Any of you guys know why this might be the case?

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    At the bottom of this thread is a list of similar threads, in particular: Is prefix faster than postfix?

    Also a quick discussion is on an external site here: Speed Optimization - Prefix vs. Postfix Incrementation and Decrementation - Music Intermix. It was one of the first results in a quick google search.

    I was surprised this seems to even be the case. Out of curiosity, how many times did you "time" it? The more the better (accurate).

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Optimizinator View Post
    Hello guys,

    After performing some C++ testing on vector iterators. I have found that the postfix-increment is faster.

    Code:
    #include <vector>
    #include <stdlib.h>
    using namespace std;
    
    class TestClass {
    	int var1, var2;
    	float floatone;
    	public: inline TestClass() {}
    };
    
    #define USE_POSTFIX 1
    
    int main( int argc, char *argv[ ] ) {
    	vector<TestClass> vectorz( 10000 );
    	vector<TestClass>::iterator viterator;
    	volatile int garbage = 0;
    	for ( unsigned int i = 0; i < 10000; i += 1 ) {
    		for ( viterator = vectorz.begin(); viterator != vectorz.end();)
    		{
    			garbage += 1; // make sure optimizer doesn't balete the loop
    			#ifdef USE_POSTFIX
    				viterator++;
    			#else
    				++viterator;
    			#endif
    		}
    	}
    }
    Timings: Prefix 5.19s user time, Postfix 4.63s user time.

    Any of you guys know why this might be the case?
    It's simply not the case; the only explanation is that you did something wrong. I don't suppose you did this?:
    Code:
    #define USE_POSTFIX 0
    Also, sometimes the second run is faster. There's no way you'll consistently get results like what you've posted.

    Your benchmarks mean nothing when you don't provide the following information:
    1. What Compiler was used
    2. Debug or Release Build
    3. What optimisation settings were used
    4. How the results were timed
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    All bets are off if all the bits and pieces are declared inline. If iterator:: operator++() is inline, and the iterator copy constructor is inline (both are likely to be the case), then the compiler gets an unfettered view of the actual semantics of the operation. It is able to see that the prior value of the iterator is unused after the post-increment, and it is able to see that the iterator's copy constructor has no side-effects. Therefore the compiler eliminate the construction and return of the prior value of the iterator.

    The fact that the postfix version comes out faster than the prefix version is probably just the vagaries of the particular compiler and optimization settings.

    Anyway, the traditional wisdom is from the old days. You actually wrote a program to test the assumption, and, provided you haven't made a mistake somewhere, you learned something counterintuitive. Bravo.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    You could try seeing the Assembly codes. They should be about the same.

  6. #6
    Registered User
    Join Date
    Jan 2010
    Posts
    2

    Why Prefix is faster than Postfix

    Prefix operation is faster when compared to postfix operation.
    Now let us see how both postfix and prefix work.

    // postfix
    iterator operator++(int)
    {
    iterator _Tmp = *this;
    ++*this;
    return (_Tmp);
    }

    // prefix
    iterator& operator++()
    {
    _Ptr = _Acc::_Next(_Ptr);
    return (*this);
    }
    note: one integer dummy variable is used in postfix operation in order to distinguish weather it is a postfix operation or prefix operation. This dummy variable is never used.
    (refer prefix / postfix overloading).

    Eliza

  7. #7
    System Novice siavoshkc's Avatar
    Join Date
    Jan 2006
    Location
    Tehran
    Posts
    1,246
    Quote Originally Posted by elizas View Post
    This dummy variable is never used.
    What do you mean the dummy var is never used? You've already used it (returned it).

    [off-topic]
    How did you ignore "Use [code] tags" warning?
    Learn C++ (C++ Books, C Books, FAQ, Forum Search)
    Code painter latest version on sourceforge DOWNLOAD NOW!
    Download FSB Data Integrity Tester.
    Siavosh K C

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I believe elizas was referring to the int in the iterator operator++(int).
    That variable is never used.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    System Novice siavoshkc's Avatar
    Join Date
    Jan 2006
    Location
    Tehran
    Posts
    1,246
    Aha, right, the type name.
    Learn C++ (C++ Books, C Books, FAQ, Forum Search)
    Code painter latest version on sourceforge DOWNLOAD NOW!
    Download FSB Data Integrity Tester.
    Siavosh K C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 03-12-2006, 02:17 PM
  2. Is prefix faster than postfix?
    By dwks in forum C Programming
    Replies: 6
    Last Post: 07-28-2005, 11:51 AM
  3. postfix and prefix
    By drdodirty2002 in forum C++ Programming
    Replies: 8
    Last Post: 09-24-2004, 06:26 AM
  4. postfix and prefix...???
    By matheo917 in forum C++ Programming
    Replies: 8
    Last Post: 04-20-2002, 01:19 PM
  5. Data Structures / prefix and postfix
    By rickc77 in forum A Brief History of Cprogramming.com
    Replies: 1
    Last Post: 12-08-2001, 12:48 PM