[ACCEPTED]-Is ++i really faster than i++ in for-loops in java?-premature-optimization
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.
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.
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.
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.
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
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.
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...
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.
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).
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
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.