Monday, March 5, 2007

Java Performance Myth

There is another discussion on our local java user group mailing list regarding java performance issue compare to application built using C/C++. One of the poster also comment on how an empty for-loop that run for 1,000,000,000 (yes, that is one-billion) iterations on java is three times slower than a c++ one.

In the beginning I started replying with the standard answer of how java requires jvm startup time which shouldn't be counted and how empty for-loop is not a good measurement, etc. By the time I finished typing the response, there are plenty of other posters responding already. So I did not even bother to send my email.

But it makes me wonder about the jvm startup time, since I heard that it has improved a lot with JSE 5 and 6 (aka 1.5 and 1.6). So I set out to do the experiment with the given parameters of doing a billion iteration of empty loop.

I decided to give the java, C, and C++ a try. My testing environment is Ubuntu 6.10 running in vmware (see my previous post). Details of the environment I used for testing are:
  • JSE JDK 5 from Sun
  • JSE JDK 6 from Sun
  • gcc & g++ 4.1 that came with the Ubuntu

I tested the following source code.

Java:


public class Loop1 {
public static void main(String[] args) {
for (int i = 0; i < 1000000000; i++) ;

}
}

public class Loop2 {
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) ;
long end = System.currentTimeMillis();
System.out.println("Time: " + (end - start)/1000.0 + "s");
}
}


C:


int main() {
int i;
for (i = 0; i < 1000000000; i++) ;

return 0;
}


C++:


int main() {
for (int i = 0; i < 1000000000; i++) ;

return 0;
}

I used the following commands to compiled those codes:
  • javac Loop1.java
  • javac Loop2.java
  • gcc loop.c -o loopc
  • gcc -O3 loop.c -o loopcO3
  • g++ loop.cpp -o loopcpp
  • g++ -O3 loop.cpp -o loopcppO3

and I run them with time command 3 times and take the average of the real time output from the time command, in the case of Loop2 I took the average from the output result.

And the result are:

Loop1 (Java5) - 1.793s
Loop2 (Java5) - 1.538s
Loop1 (Java6) - 1.468s
Loop2 (Java6) - 1.233s
loopc - 2.357s
loopcO3 - 0.008s
loopcpp - 2.384s
loopcppO3 - 0.011s

Draw your own conclusion ;P

P.S.: I also tried an empty java program, to see the startup time and to compare it with the removed for-loop for gcc/g++ compiler with -O3 flag. The average result was 0.139 seconds.

1 comment:

Anonymous said...

you should also remove JIT compilation time, also it may be useful to include server virtual machine results. As can be seen -o3 is optimizing out the empty for loop completely.