开发者

Java JRE vs GCJ

I have this results from a speed test I wrote in Java:

Java

real        0m20.626s
user        0m20.257s
sys         0m0.244s

GCJ

real        3m10.567s
user        3m5.168s
sys         0m0.676s

So, what is the purpose of GCJ then? With this results I'm sure I'm not going to compile it with GCJ!

I tested this on Linux, are the results in Windows maybe better than that?

This was the code from the application:

public static void main(String[] args) {
    String str = "";
    System.out.println("Start!!!");
    for (long i = 0; i < 5000000L; i++) {
        Math.sqrt((double) i);
        Math.pow((double) i, 2.56);
        long j = i * 745L;
        String string = new String(String.valueOf(i));
        string = string.concat(" kaka pipi"); // "Kaka pipi" is a kind of childly call in开发者_Python百科 Dutch. 
        string = new String(string.toUpperCase());
        if (i % 300 == 0) {
            str = "";
        } else {
            str += Long.toHexString(i);
        }
    }
    System.out.println("Stop!!!");
}

I compiled with GCJ like this:

gcj -c -g -O Main.java
gcj --main=speedtest.Main -o Exec Main.o

And ran like this:

time ./Exec                     // For GCJ
time java -jar SpeedTest.jar    // For Java


GCJ is obsolete. It was started a long time ago because people wanted an open-source alternative to the Sun JDK, and it was never particularly good. Now that Sun open-sourced their JDK, there's absolutely no reason to use GCJ (but it still lurks in some Linux distros).


It's not a fair comparison when you do the AOT (Ahead-Of-Time) compile with little optimisation (-O). Try at least -O2.

It's also not as simple as one is faster than the other on a single contrived test. AOT compilation works best in some scenarios. JVMs work better in others, and it also depends heavily on the quality of the JVM. In the real world, ecj is noticeably faster at building OpenJDK when AOT-compiled rather than when running on the JVM. For long-running applications, the JVM is likely to win because it can make use of dynamic optimisations not possible ahead-of-time. ecj suffers because for the short period it's compiling, the JVM is still interpreting code. HotSpot compiles and optimises code when it determines it's worthwhile (a 'hot spot').

BTW, it's the FAQ that's out of date. GCJ supports most of 1.5, certainly enough to build OpenJDK. Without GCJ still 'lurking in some Linux distros', it wouldn't be possible to build OpenJDK in the first place.


On x86 and AMD64, Hotspot only uses SSE for floating point, but I see that on x86 gcj doesn't seem to support SSE and uses the much slower 387 instructions:

gcj -O3 -mfpmath=sse --main=Bench Bench.java -o Bench
jc1: warning: SSE instruction set disabled, using 387 arithmetics
/tmp/ccRyR50H.i:1: warning: SSE instruction set disabled, using 387 arithmetics

so that could explain the speed difference.

Note that when GCC does use SSE, it greatly outperforms Hotspot on floating point, since GCC generates SIMD instructions while Hotspot only uses the unpacked SSE arithmetic.


OpenJDK's native Java compiler is, itself, written in Java; as a consequence, you need a working previous version of Java in order to build a new version.

If you're starting from scratch on a platform for which no existing JDK binaries are readily available (or if you're working within certain Free Software projects whose charters prohibit the use of proprietary build dependencies), then GCJ (or some of its underlying components) can be one potential solution to the chicken-and-egg problem of getting a working, albeit somewhat inefficient bootstrap Java in place, in order to move on to build the more desirable OpenJDK.

In fact, back when OpenJDK was first announced, significant effort (via the IcedTea project) was spent in fixing up GCJ to get it to the point where it was up to the task.


"So, what is the purpose of GCJ then?"

Some have pointed that your "benchmark" isn't fair. However, even if it was, I can still see a use for GCJ. Suppose you want to write a kernel in Java. With a JVM, you have to port the VM to a standalone environment, and then you would have to write the low lever code in C. With an AOT compiler, you can work around this issue with some glue code and then can do the low level code in Java too. No need to port the compiler in this case.

Also, we have to separate the technique from the benchmarks. Perhaps the AOT technique can be more powerful than the JIT technique provided that we invest enough development effort in it.


You have stumbled onto another product of the "Software Freedom at any cost!" line of thinking. GCJ was created to allow compilation and execution of Java code without depending on anything deemed "non-free" by GNU project.

If you value software freedom enough to take a 12x performance hit, then by all means, go for it!

The rest of us will happily use Sun's (er, Oracle's) incredible HotSpot JVM.

See also: The GCJ FAQ: "I have just compiled and benchmarked my Java application and it seems to be running slower than than XXX JIT JVM. Is there anything I can do to make it go faster?"

Also: "It has been merged with GNU Classpath and supports most of the 1.4 libraries plus some 1.5 additions." So it's just a bit out of date as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜