my crude benchmark results

Bryce McKinlay mckinlay@redhat.com
Tue Jul 13 17:45:00 GMT 2004


John Gabriele wrote:

> A friend was just asking me about speed when using Java
> for trig, so I put together a small program to get some
> *very* crude benchmark results. See the end of this email
> for the source code text. It's in C as well as Java. I'm on
> Mac OS X at the moment (a 500 MHz G3 with 256 MB),
> and I compared the C program with Apple's JVM as well as
> with GCJ 3.4.0.
>
> Time taken to run:
>
>     in C:
>     8.5 seconds
>
>     Java via Apple's JVM:
>     22.2 seconds
>
>     Java via GCJ:
>     25.5 seconds


In GCC 3.4.x and until very recently, GCJ on Darwin has been at a pretty 
severe disadvantage because it lacked the code to convert segfault 
signals into NullPointerExceptions. That means that for every object or 
array access it has to insert an explicit check for null. Of course, in 
this case it should be smart enough to optimize many of them away, but I 
wouldn't be completely surprised if its failing to do that completely, 
resulting in the difference between Apple's JVM and GCJ that you see here.

With GCC head on x86 linux (3.2ghz P4), I got the following results from 
your benchmarks:

$ gcc main.c -o c-bench -O2 -lm
$ /usr/bin/time ./c-bench
Size = 50000
Sum = 50000.000000
1.63user 0.01system 0:01.65elapsed

$ gcj -O2 Main.java --main=Main
$ /usr/bin/time ./a.out
Size = 50000
Sum = 50000.0
7.84user 0.02system 0:07.87elapsed

$ /usr/bin/time java Main
Size = 50000
Sum = 50000.0
11.50user 0.09system 0:11.86elapsed

These results were pretty consistent over multiple iterations, so GCJ is 
beating the JDK 1.5 beta hotspot client VM quite nicely for this test.

But, theres another option you should know about. With --fast-math 
(which causes the Math.* calls to be inlined directly into FPU 
instructions), the performance improves dramatically:

$ gcj -O2 Main.java --main=Main --fast-math
$ /usr/bin/time ./a.out
Size = 50000
Sum = 50000.0
1.18user 0.01system 0:01.19elapsed

In fact, its now faster than the C version ;-).

> Of course, considering that GCJ is Free software, and the large
> number of platforms it runs on, I'm quite happy with it. Still though,
> it's surprising how much faster C is than Java for this simple
> procedural code.


I think the main problem here, judging by the huge difference shown by 
--fast-math, is that we implement the Math.* calls inefficiently. In 
libjava we use the fdlibm library to implement them, which is written in 
pure C and contains no cpu-specific asm optimizations. On systems that 
have a Java-compatible math library, we should use the system library 
instead of fdlibm.

Regards

Bryce



More information about the Java mailing list