1

so I get it that pre-increment is faster than post-increment as no copy of the value is made. But let's say I have this:

char * temp = "abc"; 
char c = 0; 

Now if I want to assign 'a' to c and increment temp so that it now points to 'b' I would do it like this :

c = *temp++; 

but pre-increment should be faster so i thought :

c = *temp; 
++temp;

but it turns out *temp++ is faster according to my measurements.

Now I don't quite get it why and how, so if someone is willing to enlighten me, please do.

  • 6
    Look at generated assembly code. – hyde Sep 11 '18 at 08:46
  • 6
    Did you compile with optimizations? – Rakete1111 Sep 11 '18 at 08:47
  • 6
    How did you measure? – UnholySheep Sep 11 '18 at 08:47
  • To cut to the chase, what you are asking is irrelevant and pointless. Answer is "it just doesn't work like that". – hyde Sep 11 '18 at 08:55
  • How did you set up the test? What statistical model did you use? What was the standard deviation of the mean of the time for both cases? – Bathsheba Sep 11 '18 at 09:06
  • @Bathsheba It was just a quick testing, while I was playing around with chrono library. I know it's pointless and stupid to measure it like that, but it had some differences. Looking at assembly code I noticed that first option with post-increment uses LEA instruction, which could be the reason. Thanks for answers. – Stefan Gajanovic Sep 11 '18 at 09:26
  • @StefanGajanovic: The question would have been an order of magnitude better had you mentioned the LEA instruction in the question. – Bathsheba Sep 11 '18 at 09:27
  • @StefanGajanovic : I have just added an illustration to my answer that explains why you're (likely) seeing the speed difference. It's not the lea instruction (that's just used to perform the increment). – Sander De Dycker Sep 11 '18 at 09:33

1 Answers1

2

First, pre-increment is only potentially faster for the reason you state. But for basic types like pointers, in practice that's not the case, because the compiler can generate optimized code. Ref. Is there a performance difference between i++ and ++i in C++? for more details.

Second, to a decent optimizing compiler, there's no difference between the two alternatives you mentioned. It's very likely the same exact machine code will be generated for both cases (unless you disabled optimizations).

To illustrate this : on my compiler, the following code is generated when optimizations are disabled :

# c = *temp++;
movq    temp(%rip), %rax
leaq    1(%rax), %rdx
movq    %rdx, temp(%rip)
movzbl  (%rax), %eax
movb    %al, c(%rip)

# c = *temp;
movq    temp(%rip), %rax
movzbl  (%rax), %eax
movb    %al, c(%rip)
# ++temp;
movq    temp(%rip), %rax
addq    $1, %rax
movq    %rax, temp(%rip)

Notice there's an additional movq instruction in the latter, which could account for slower run time.

When enabling optimizations however, this turns into :

# c = *temp++;
movq    temp(%rip), %rax
leaq    1(%rax), %rdx
movq    %rdx, temp(%rip)
movzbl  (%rax), %eax
movb    %al, c(%rip)

# c = *temp;
# ++temp;
movq    temp(%rip), %rax
movzbl  (%rax), %edx
addq    $1, %rax
movq    %rax, temp(%rip)
movb    %dl, c(%rip)

Other than a different order of the instructions, and the choice of using addq vs. leaq for the increment, there's no real difference between these two. If you do get (measurably) different performance between these two, then that's likely due to the specific cpu architecture (possibly a more optimal use of the pipeline eg.).

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40