In java I usually make a for-loop like following:
for (int i = 0; i < max; i++) {
something
}
But recently a colleague typed it so:
for (int i = 0; i < max; ++i) {
something
}
He said the latter would be faster. Is that true?
In java I usually make a for-loop like following:
for (int i = 0; i < max; i++) {
something
}
But recently a colleague typed it so:
for (int i = 0; i < max; ++i) {
something
}
He said the latter would be faster. Is that true?
On
In Java there should be no difference - any modern compiler* should generate the same byte code (just an iinc) in both cases since the result of the increment expression is not being used directly.
There is a third option, still the same byte code*:
for (int i = 0; i < max; i += 1) {
something
}
* tested with Eclipse's compiler
On
No there will be no difference at all.
This came from C++ but even there there would be no difference at all in this case. Where there is a difference is where i is an object. i++ would have to make an additional copy of the object as it has to return the original unchanged value of the item whereas ++i can return the changed object so saves a copy.
In c++ with user defined object the cost of a copy can be significant so it's definatly worth remembering. And because of this people tend to use it for int variables too, as it's just as good anyway...
On
This question needed some Java byte code. Consider 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 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.
On
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 even if it is not that much, I asume there is a difference
On
In Java there is no such difference. Java machine interpertes code and no matter if you write ++i or i++, it will be converted to byte code to exact same instruction set.
But in C/C++ there is a huge difference and if you are not using any optimisation flags, then your loop can be slower up to 3 times.
Using optimisation flags such like -O/-O3 will force compiler to make output asembly code simplier (in most cases) and therefore faster (in most cases).
No, it's not true. You could measure the performance by timing each loop for a large number of iterations, but I'm fairly certain they will be the same.
The myth came from C where
++iwas regarded as faster thani++because the former can be implemented by incremeting i then returning it. The latter might be implemented by copying the value of i to a temporary variable, incrementing i, then returning the temporary. The first version doesn't need to make the temporary copy and so many people assume that it is faster. However if the expression is used as a statement modern C compilers can optimize the temporary copy away so that there will be no difference in practice.