Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Analysis of various incremental operators vs assignment and incrementing

Tags:

java

bytecode

So someone asked Is the ++ operator more efficient than a=a+1? a little while ago. I thought that I analyzed this before and initially said that there was no difference between a = a + 1 and the incremental operator ++. As it turns out, a++, ++a and a += 1 all compile to the same bytecode, but a = a + 1 does not, as can be seen below:

public class SO_Test
{
    public static void main(String[] args)
    {
        int a = 1;
        a++;
        a += 1;
        ++a;    
    }
}

Output: enter image description here

Example:

public class SO_Test
{
    public static void main(String[] args)
    {
        int a = 1;
        a = a + 1;
        a++;
        a += 1;
        ++a;    
    }
}

Output: enter image description here

In short, a = a + 1 issues iload_1, iconst_1, iadd and istore_1, whereas the others only use iinc.

I've tried to rationalize this, but I am unable to. Is the compiler not smart enough to optimize the bytecode in this case? Is there a good reason that these are different? Is this handled by JIT? Unless I'm interpreting this incorrectly, it seems like I should never use a = a + 1, which I thought for sure was just a stylistic choice.

like image 249
Steve P. Avatar asked Nov 13 '13 15:11

Steve P.


2 Answers

The prevailing philosophy is that javac deliberately chooses not to optimize generated code, relying on the JIT compiler to do that at runtime. The latter has far better information about the execution environment (hardware architecture etc) as well as how the code is being used at runtime.

These days, I don't think you can draw any realistic conclusions about performance from just reading the bytecodes. Arguments about premature optimization aside, if you really want to know if there's a difference, construct a micro-benchmark and see for yourself.

like image 166
NPE Avatar answered Nov 18 '22 15:11

NPE


It’s worth noting that this is compiler specific. I found at least one eclipse version compiling x=x+1 the same way as x++. Further, this is relevant to local variables only, as there is no similar byte code instruction for fields. And it works for variables of type int only. So the byte code impact is rather limited. It’s most likely there to improve the common for(int i=start; i<limit; i++) pattern. On the language side it makes a difference especially for a[b()] ++ vs. a[b()] = a[b()] + 1, etc.

like image 1
Holger Avatar answered Nov 18 '22 13:11

Holger