8

Is there any performance difference between using int a=a+1 and a++ in Java?

If so which is better and why? Could you briefly explain me to understand this?

Bikramjeet Singh
  • 681
  • 1
  • 7
  • 22
Surya Chandra
  • 1,561
  • 5
  • 27
  • 42
  • 4
    concidering micro-optimizations: always do what is more readable, let the compiler optimize for you. Code is for programmers, optimizations are for compilers. – amit Feb 15 '12 at 11:26
  • 4
    asking this question cost's you more time than the runtime advantage of the faster (if there is any) solution. – Bernhard Kircher Feb 15 '12 at 11:29
  • 2
    @Bernhard: I just wanted to know whether there is any difference – Surya Chandra Feb 15 '12 at 11:32

6 Answers6

15

First of all, the Java Language Specification doesn't say anything about timing. But assuming we're using a typical compiler such as Suns javac we see that all of the above examples (a++, ++a, a += 1, a = a + 1) could either be compiled into something like:

  • iinc instruction, working on variables:

    iload_<variable>
    iinc <variable>, 1
    istore_<variable>
    
  • iadd instuction, using the stack (here using variable 1 as a the storage):

    iload_1
    iconst_1
    iadd
    istore_1
    

It's up to the compiler to choose the best possible way to compile them. E.g. there is no difference between them. And it shouldn't be any difference between the statements - they all express the same thing - adding one to a number.

That beeing said, both the iinc and the iadd version can be compiled using the JIT to something fast and platform dependent, and in the end I would assume that a normal runtime compiles both versions into the same assembler code.


With my compiler, *jdk1.6.0_20* the "increment" methods even uses the same instruction.

public class Test {
    public static void main(String[] args) {

        int a = 0;

        a = a + 1;
        a += 1;
        a++;
        ++a;
    }
}

This is the disassembly:

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iinc    1, 1   // a = a + 1;
   5:   iinc    1, 1   // a += 1;
   8:   iinc    1, 1   // a++;
   11:  iinc    1, 1   // ++a;
   14:  return

}
dacwe
  • 43,066
  • 12
  • 116
  • 140
  • can you pls. add details for `++a` also? – Azodious Feb 15 '12 at 11:45
  • @Azodious: Depends on the case, if I just add `++a;` to the above statements it will just convert it to an another `iinc 1, 1`. However in a more complex scenario the ordering of the instructions will is different (see this [SO post](http://stackoverflow.com/questions/5413548/java-prefix-postfix-of-increment-decrement-operators-need-help-with-example)). – dacwe Feb 15 '12 at 11:52
  • I think at "iinc instruction, working on variables" there is a mistake. `iinc` does not need `iload` and `istore` (?) – Johannes Oct 22 '15 at 07:39
3

Looking at the generated bytecode:

public static void main(String[] args) {
    int x = 1;
    int y = 1;
    int z = 1;
    int a = 1;
    int b = 1;
    x = x + 1;
    y++;
    ++z;
    a += 1;
    b += 2;
}

generates (use javap -c classname)

0:   iconst_1
1:   istore_1
2:   iconst_1
3:   istore_2
4:   iconst_1
5:   istore_3
6:   iconst_1
7:   istore  4
9:   iconst_1
10:  istore  5
12:  iload_1
13:  iconst_1
14:  iadd
15:  istore_1
16:  iinc    2, 1
19:  iinc    3, 1
22:  iinc    4, 1
25:  iinc    5, 2
28:  return

So using (jdk1.6.0_18):

x = x + 1

creates

12:  iload_1
13:  iconst_1
14:  iadd
15:  istore_1

whereas

y++;
++z;
a += 1;

all result in

iinc

However, doing a rough performance test on my laptop resulted in next to no difference in the runtime between the two (sometimes ++x was quicker, sometimes x=x+1 was quicker), so I wouldn't worry about the performance implications.

beny23
  • 34,390
  • 5
  • 82
  • 85
  • 1
    And the lesson you should learn from this is that you cannot infer Java performance by counting bytecodes! (Not even if you run with `java -int ...` to turn of JIT compilation.) – Stephen C Nov 13 '13 at 15:13
2

No, there won't be any noticeable difference. Use what you find the most readable (which is a++, normally).

First rule of code optimization: don't.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    I didnt downvote but actually i dont agree with your point. From a clean code perspective `a+=1` is at least from my perspective a more solid approach both for readability and fault tolerance. Did you ever evaluate `a+++b`(in Java and C++) ? The only argument for a++ was the different processor instruction but this is nowerdays optimized by the JVM. – fyr Feb 15 '12 at 11:35
  • we're not discussing a+++b here. We're discussing a++, which is the instruction meaning "*increment a*". It's readable by any Java developer, and there is no understandability problem with this instruction. – JB Nizet Feb 15 '12 at 12:10
  • Thats exactly the point everybody should understand it. But it is not saying "increment a". The meaning of a++ is "increment a after the current expression" – fyr Feb 15 '12 at 12:13
  • Not when the expression used is just `a++`. In this case, it doesn't matter if the increment is done before or after the assignment: there is no assignment. That was the question of the OP: `a = a + 1` or `a++`? – JB Nizet Feb 15 '12 at 12:23
1

The compiler should optimize and there should be no difference at all. But keep in mind that prefix increment operator may be (it depends by the compiler) faster than the postfix equivalent (in C++ and C# also):

++a faster than a++ because the postfix operator must create a temporary variable.. think about their implementation:

prefix:

a = a + 1;
return a;

postfix:

int tmp = a;
a = a + 1;
return tmp;
vulkanino
  • 9,074
  • 7
  • 44
  • 71
  • nop: http://stackoverflow.com/questions/24886/is-there-a-performance-difference-between-i-and-i-in-c – assylias Feb 15 '12 at 11:32
  • as I said: **may be**. not all compilers optimize that way though. – vulkanino Feb 15 '12 at 11:38
  • @vulkanino: must read for you: http://stackoverflow.com/questions/4638364/undefined-behavior-and-sequence-points-reloaded – fyr Feb 15 '12 at 11:44
0

a++ is much faster. It converts to INC command of assembler.But I think JVM will optimize a=a+1 so you don't need to care about that.

shift66
  • 11,760
  • 13
  • 50
  • 83
0

It's the same, and nowadays with compiler optimization should not be aware of that stuff, to increase your performance check other bigger issues like allocs :)

Mario Corchero
  • 5,257
  • 5
  • 33
  • 59