[ACCEPTED]-Is ++i really faster than i++ in for-loops in java?-premature-optimization

Accepted answer
Score: 62

No, it's not true. You could measure the 15 performance by timing each loop for a large 14 number of iterations, but I'm fairly certain 13 they will be the same.

The myth came from 12 C where ++i was regarded as faster than i++ because 11 the former can be implemented by incremeting 10 i then returning it. The latter might be 9 implemented by copying the value of i to 8 a temporary variable, incrementing i, then 7 returning the temporary. The first version 6 doesn't need to make the temporary copy 5 and so many people assume that it is faster. However 4 if the expression is used as a statement 3 modern C compilers can optimize the temporary 2 copy away so that there will be no difference 1 in practice.

Score: 46

This question needed some Java byte code. Consider 2 the following code:

public class PostPre {
    public static void main(String args[]) {
        int n = 5;
        loop1(n);
        loop2(n);
    }

    public static void loop1(int n) {
        for (int i = 0; i < n; i++) {}
    }

    public static void loop2(int n) {
        for (int i = 0; i < n; ++i) {}
    }
}

Now compile it and disassemble 1 it:

$ javac PostPre.java; javap -c PostPre.class 
Compiled from "PostPre.java"
public class PostPre {
  public PostPre();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: iconst_5      
       1: istore_1      
       2: iload_1       
       3: invokestatic  #2                  // Method loop1:(I)V
       6: iload_1       
       7: invokestatic  #3                  // Method loop2:(I)V
      10: return        

  public static void loop1(int);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: iload_0       
       4: if_icmpge     13
       7: iinc          1, 1
      10: goto          2
      13: return        

  public static void loop2(int);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: iload_0       
       4: if_icmpge     13
       7: iinc          1, 1
      10: goto          2
      13: return        
}

loop1() and loop2() have the same byte code.

Score: 9

For any reasonably capable optimizer, they 3 will be exactly the same. If you aren't 2 sure, look at the output bytecode or profile 1 it.

Score: 6

Even if it is, which I very much doubt, your 3 colleague should really have better things 2 to spend his time learning than how to optimise 1 a loop expression.

Score: 2

Try this in your environment

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

        long foo; //make sure the value of i is used inside the loop
        long now = 0; 
        long prefix = 0;
        long postfix = 0;

        for (;;) {
            foo = 0;
            now = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; i++) {
                foo += i;
            }
            postfix = System.currentTimeMillis() - now;

            foo = 0;
            now = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; ++i) {
                foo += i;
            }
            prefix = System.currentTimeMillis() - now;

            System.out.println("i++ " + postfix + " ++i " + prefix + " foo " + foo);
        }
    }
}

Mine gives me

i++ 1690 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1600 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1611 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1691 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1600 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1691 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1691 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1692 ++i 1610 foo 499999999500000000
i++ 1701 ++i 1610 foo 499999999500000000
i++ 1691 ++i 1610 foo 499999999500000000

So 2 even if it is not that much, I asume there 1 is a difference

Score: 1

It will not be any faster. The compiler 5 and JVM with the JIT will make mincemeat 4 of such insignificant differences.

You can 3 use the usual loop optimization techniques 2 to get speed benefits, like unrolling, if 1 applicable.

Score: 1

No there will be no difference at all.

This 12 came from C++ but even there there would 11 be no difference at all in this case. Where 10 there is a difference is where i is an object. i++ would 9 have to make an additional copy of the object 8 as it has to return the original unchanged 7 value of the item whereas ++i can return 6 the changed object so saves a copy.

In c++ with 5 user defined object the cost of a copy can 4 be significant so it's definatly worth remembering. And 3 because of this people tend to use it for 2 int variables too, as it's just as good 1 anyway...

Score: 1

Decompile with "javap -c YourClassName" and 5 see the result and decide from that. This 4 way you see what the compiler actually does 3 at each case, not what you think it does. This 2 way you also see WHY one way is faster than 1 the other.

Score: 1

In Java there is no such difference. Java 10 machine interpertes code and no matter if 9 you write ++i or i++, it will be converted 8 to byte code to exact same instruction set.

But 7 in C/C++ there is a huge difference and 6 if you are not using any optimisation flags, then 5 your loop can be slower up to 3 times.

Using 4 optimisation flags such like -O/-O3 will 3 force compiler to make output asembly code 2 simplier (in most cases) and therefore faster 1 (in most cases).

Score: 0

In Java there should be no difference - any 5 modern compiler* should generate the same 4 byte code (just an iinc) in both cases since 3 the result of the increment expression is 2 not being used directly.
There is a third option, still 1 the same byte code*:

for (int i = 0; i < max; i += 1) {
   something
}

* tested with Eclipse's compiler

More Related questions