Skip to content

Pre-increment vs. Post-increment: Which is Faster for 3D Software Development?

ADMIN | 11-02-2011

I was asked recently, “Did you know that pre-increment was faster than post-increment?” I answered, “No”.

Hexagon pattern 1

By Kevin Tatterson

It was fun writing my first two blog posts – because I like pushing people’s buttons with controversial, philosophical subjects.  But for this article, I’d like to get technical.

Pre-increment vs. Post-increment in 3D Software Development

I was asked recently, “Did you know that pre-increment was faster than post-increment?”  I answered, “No”.  The claim:

                                                            ++d is faster than d++

The explanation:  the implementation of post-increment (d++) must create a temporary storage for housing the original value of d, increment/store d, and return the original temporary value.  In contrast, pre-increment (++d) only has to increment/store the value and return it – no temporary required. 

To put things in programming speak, suppose we implement our own integer class and implement the overloads for pre and post-increment:

class myint

{

       int n;

 

public:

       myint( int _n ): n(_n) {}

 

       myint( const myint & m )

       {

              n = myint.n;

       }

 

       myint& operator++()  // prefix, e.g., ++n

       {

n = n + 1;

return n;
}

 

       myint operator++(int) // postfix, e.g., n++

{

       myint m(*this);      // create the temporary

       n = n + 1;

       return m;

}

};

 

On the surface – it is clear that post-increment is doing more work – because it has to “create the temporary”.  But is it measurable?  Let’s look at this through a couple different lenses.

 

 

Lense #1:  basic types

 

More than one person has studied this and all have found the same conclusion:  for basic types (int, double, etc.), ++d has the same performance as d++.  I’ve seen a couple good studies that break things down right to the exact assembly instructions.  Here’s a good study 

 

Lense #2:  really simple objects

 

The “myint” class above is a good example of a “really simple object”.  Essentially, the goal of the design is to mimic an integer type – yet allow control over the precise implementation of each operator overload – in particular, the ones we want to measure:  pre-increment and post-increment.

 

Suppose we put myint’s pre-increment and post-increment under the empirical microscope – and try to measure the performance difference.  Here’s the program:

 

clock_t start;

       const int iters = 800000000;

       {

              myint m(0);

              start = clock();

              for ( int i = 0; i < iters; i++ )

                     m++;

              printf( "post incr time: %d\n ms", clock() - start );

       }

 

       {

              myint d(0);

              start = clock();

              for ( int i = 0; i < iters; i++ )

                     ++d;

              printf( "pre incr time: %d ms\n", clock() - start );

       }

 

The first problem we run into is the compiler optimizer.  As written above, the Microsoft VS 2005 compiler optimizer completely optimizes the loop away, avoiding it altogether!  This defeats our desire to measure the overhead cost of pre- vs. post-increment.

 

One low-cost trick to “calm” the optimizer is to add a __asm nop block to the implementations of our pre- and post-increment methods.  The biggest downside to this approach is that the __asm  directive prevents the optimizer from inlining – and for our “really simple object”, this can make a big difference.  Let’s get back to the inlining issue later – for now, here’s what the __asm nop code looks like:

 

       myint& operator++()  // prefix, e.g., ++n

       {

              __asm { nop }

n = n + 1;

return n;
}

 

       myint operator++(int) // postfix, e.g., n++

{

              __asm { nop }

       myint m(*this);      // create the temporary

       n = n + 1;

       return m;

}

 

With the __asm nop blocks in place, we can start to run some benchmarks.  Repeated runs converge on the following times:

 

post incr time: 1781 ms

pre incr time: 1515 ms

 

This means pre-increment is 15% faster than post-increment.  But is it believable?  Let’s look at the generated assembly and compare clock cycles:

 

Pre-increment

Clock cycles

Post-increment

Clock cycles

lea ecx,[esp+10h]

1

push 0

1

call myint::operator++

3

lea eax,[esp+18h]

1

     mov eax,ecx

1

push eax

1

     nop

1

lea ecx,[esp+18h]

1

     add dword ptr [eax],1

3

call myint::operator++

3

     ret

5

     nop

1

 

 

     mov edx,dword ptr [ecx]

1

 

 

     mov dword ptr [eax],edx

1

 

 

     add edx,1

1

 

 

     mov dword ptr [ecx],edx

1

 

 

     ret

5

sub ebx,1

1

sub ebx,1

1

jne class_int_bench+61h

3

jne class_int_bench+61h

3

TOTAL clocks

18

TOTAL clocks

21

 

The assembly instructions shown above are the exact instructions being timed – and hence, represent the cost of each iteration of the loop.  The performance improvement based on total clocks:  14.3%.  This compares nicely to the empirical data, 15%.

Next Post:

I will push this a little into the theoretical (with respect to inlining), then tear it all down with a just a small dose of reality.

You might also like...

5 Min read
CGM Modeler
Software components are like the stage crew at a big concert performance: the audience doesn’t see them, but their...
8 Min read
CGM Modeler
There’s a lot of confusion around what the terms additive manufacturing and 3D printing mean.
2 Min read
CGM Modeler
WRL files are an extension of the Virtual Reality Modeling Language (VRML) format . VRML file types enable browser...
Voxel model example
3 Min read
CGM Modeler
Voxels are to 3D what pixels are to 2D. Firstly -- let’s examine what pixels actually are. Everything you see on your...
Point_cloud_torus
2 Min read
CGM Modeler
Point-cloud modeling is typically used in the process of 3D scanning objects. Rather than defining surfaces through...
Polygonal Modeling
2 Min read
CGM Modeler
Polygonal (or polyhedral) modeling is the most common type of modeling for video games and animation studios. This type...
BREP Model example
2 Min read
CGM Modeler
BRep modeling, or Boundary Representation modeling, is, in CAD applications, the most common type of modeling. BRep is...
Construction site with crane and building-1
3 Min read
3D Software Development Kits
Digital twins are changing the way the construction industry manages large building projects and infrastructure...
3 Min read
3D Software Development Kits
There is a new wave of innovative processes and solutions that improve product production throughput, and enable...
3D Product Visualization.jpg
2 Min read
3D Software Development Kits
In the 3D modeling space, application developers face a number of challenges — getting to market on time, delivering...
General PMI
4 Min read
3D Software Development Kits
It has already been a year since release 2017 1.0, which saw the introduction of a number of innovative features aimed...
Large Tolerant  Vertex
3 Min read
3D Software Development Kits
boolean operation Boolean operations on individual bodies are common functions in 3D modeling. While simple in concept,...
3 Min read
3D Software Development Kits
In much the same way as physical design has moved from paper 2D drawings to 3D models in software, so has analysis....
2 Min read
3D Software Development Kits
Today was day one of Spatial Corp.’s 3D Insiders’ Summit 2016, an educational event that focuses on technical topics...
4 Min read
3D InterOp
Part and parcel with model-based engineering is model translation. Because the model is now the specification, accurate...
3 Min read
3D Software Development Kits
In case you missed the news this week, we announced the availability of Release 2017 1.0 for Spatial software...
2 Min read
3D Software Development Kits
Augmented World Expo 2016
4 Min read
3D Software Development Kits
Make or buy is an age old question for anyone building products, whether hardware or software. For example, for a...