Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does n++ execute faster than n=n+1?

People also ask

Which is better'n ++ or N 1?

As you can see in the assembly, GCC simply converts n++ into n=n+1 , then optimizes it into the one-instruction add (in the -O2). Your instructor's suggestion that n++ is faster only applies to very old, non-optimizing compilers, which were not smart enough to select the in-place update instructions for n = n + 1 .

Why increment operator is faster?

Pre-increment is faster than post-increment because post increment keeps a copy of previous (existing) value and adds 1 in the existing value while pre-increment is simply adds 1 without keeping the existing value.

Which executes faster between i ++ increment operator and II 1?

As i++ does automatic typecasting and uses a compiler instruction which internally uses iadd instruction, i=i+1 is faster than i++.

Which is faster A A 1 or A ++ explain?

a++ is better than a+1 because in the case of floating point numbers a++ increments more efficiently than a=a+1.


That would be true if you are working on a "stone-age" compiler...

In case of "stone-age":
++n is faster than n++ is faster than n=n+1
Machine usually have increment x as well as add const to x

  • In case of n++, you will have 2 memory access only (read n, inc n, write n )
  • In case of n=n+1, you will have 3 memory access (read n, read const, add n and const, write n)

But today's compiler will automatically convert n=n+1 to ++n, and it will do more than you may imagine!!

Also on today's out-of-order processors -despite the case of "stone-age" compiler- runtime may not be affected at all in many cases!!

Related


On GCC 4.4.3 for x86, with or without optimizations, they compile to the exact same assembly code, and thus take the same amount of time to execute. As you can see in the assembly, GCC simply converts n++ into n=n+1, then optimizes it into the one-instruction add (in the -O2).

Your instructor's suggestion that n++ is faster only applies to very old, non-optimizing compilers, which were not smart enough to select the in-place update instructions for n = n + 1. These compilers have been obsolete in the PC world for years, but may still be found for weird proprietary embedded platforms.

C code:

int n;

void nplusplus() {
    n++;
}

void nplusone() {
    n = n + 1;
}

Output assembly (no optimizations):

    .file   "test.c"
    .comm   n,4,4
    .text
.globl nplusplus
    .type   nplusplus, @function
nplusplus:
    pushl   %ebp
    movl    %esp, %ebp
    movl    n, %eax
    addl    $1, %eax
    movl    %eax, n
    popl    %ebp
    ret
    .size   nplusplus, .-nplusplus
.globl nplusone
    .type   nplusone, @function
nplusone:
    pushl   %ebp
    movl    %esp, %ebp
    movl    n, %eax
    addl    $1, %eax
    movl    %eax, n
    popl    %ebp
    ret
    .size   nplusone, .-nplusone
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

Output assembly (with -O2 optimizations):

    .file   "test.c"
    .text
    .p2align 4,,15
.globl nplusplus
    .type   nplusplus, @function
nplusplus:
    pushl   %ebp
    movl    %esp, %ebp
    addl    $1, n
    popl    %ebp
    ret
    .size   nplusplus, .-nplusplus
    .p2align 4,,15
.globl nplusone
    .type   nplusone, @function
nplusone:
    pushl   %ebp
    movl    %esp, %ebp
    addl    $1, n
    popl    %ebp
    ret
    .size   nplusone, .-nplusone
    .comm   n,4,4
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

The compiler will optimize n + 1 into nothingness.

Do you mean n = n + 1?

If so, they will compile to identical assembly. (Assuming that optimizations are on and that they're statements, not expressions)


Who says it does? Your compiler optimizes it all away, really, making it a moot point.


Modern compilers should be able to recognize both forms as equivalent and convert them to the format that works best on your target platform. There is one exception to this rule: variable accesses that have side effects. For example, if n is some memory-mapped hardware register, reading from it and writing to it may do more than just transferring a data value (reading might clear an interrupt, for instance). You would use the volatile keyword to let the compiler know that it needs to be careful about optimizing accesses to n, and in that case the compiler might generate different code from n++ (increment operation) and n = n + 1 (read, add, and store operations). However for normal variables, the compiler should optimize both forms to the same thing.