Java JRE 与 GCJ

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3032727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:47:16  来源:igfitidea点击:

Java JRE vs GCJ

javaperformancegcj

提问by Martijn Courteaux

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

我从我用 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!

那么,GCJ 的目的是什么?有了这个结果,我确定我不会用 GCJ 编译它!

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

我在 Linux 上测试了这个,在 Windows 中的结果可能比那更好吗?

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 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 编译是这样的:

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

采纳答案by Mike Baranczak

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).

GCJ 已经过时了。它在很久以前就开始了,因为人们想要一个开源的 Sun JDK 替代品,而且它从来都不是特别好。现在 Sun 开源了他们的 JDK,绝对没有理由使用 GCJ(但它仍然潜伏在一些 Linux 发行版中)。

回答by Mark Renouf

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.

您偶然发现了“不惜一切代价获得软件自由”的另一种产品!思路。GCJ 的创建是为了允许编译和执行 Java 代码,而不依赖于任何被 GNU 项目视为“非自由”的东西。

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

如果您非常重视软件自由度以达到 12 倍的性能提升,那么无论如何,去吧!

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

我们其他人会很高兴地使用 Sun 的(呃,Oracle 的)令人难以置信的 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?"

另请参阅:GCJ 常见问题解答:“我刚刚编译了我的 Java 应用程序并对其进行了基准测试,它的运行速度似乎比 XXX JIT JVM 慢。有什么我可以做的让它运行​​得更快吗?”

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 bitout of date as well.

另外:“它已与 GNU Classpath 合并,并支持大多数 1.4 库以及一些 1.5 附加库。” 所以它也有点过时了。

回答by Andrew John Hughes

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

当您使用很少的优化 (-O) 进行 AOT(Ahead-Of-Time)编译时,这不是一个公平的比较。至少尝试 -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').

它也不像在一次人为的测试中一个比另一个快那么简单。AOT 编译在某些情况下效果最好。JVM 在其他方面表现得更好,这也很大程度上取决于 JVM 的质量。在现实世界中,ecj 在 AOT 编译时构建 OpenJDK 的速度明显快于在 JVM 上运行时。对于长时间运行的应用程序,JVM 可能会胜出,因为它可以利用无法提前实现的动态优化。ecj 受到影响,因为在它编译的短时间内,JVM 仍在解释代码。HotSpot 在确定值得(“热点”)时编译和优化代码。

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.

顺便说一句,这是过时的常见问题解答。GCJ 支持 1.5 的大部分,当然足以构建 OpenJDK。如果 GCJ 仍然“潜伏在某些 Linux 发行版中”,那么首先就不可能构建 OpenJDK。

回答by damjan

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:

在 x86 和 AMD64 上,Hotspot 仅将 SSE 用于浮点,但我看到在 x86 上 gcj 似乎不支持 SSE 并使用慢得多的 387 指令:

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.

请注意,当 GCC 确实使用 SSE 时,它在浮点上的性能大大优于 Hotspot,因为 GCC 生成 SIMD 指令,而 Hotspot 仅使用未打包的 SSE 算法。

回答by Jo?o Jerónimo

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

“那么,GCJ的目的是什么?”

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.

有些人指出你的“基准”不公平。但是,即使是这样,我仍然可以看到 GCJ 的用途。假设您想用 Java 编写内核。使用 JVM,您必须将 VM 移植到独立环境,然后您必须用 C 编写低级别代码。使用 AOT 编译器,您可以使用一些胶水代码解决此问题,然后可以执行低级别代码Java中的级别代码也是如此。在这种情况下不需要移植编译器。

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.

此外,我们必须将技术与基准分开。也许 AOT 技术可以比 JIT 技术更强大,前提是我们在它上面投入了足够的开发精力。

回答by Jo?o Jerónimo

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.

OpenJDK 的原生 Java 编译器本身是用 Java 编写的;因此,您需要一个可用的 Java 以前版本才能构建新版本。

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.

如果您在一个没有现成 JDK 二进制文件可用的平台上从头开始(或者如果您正在某些自由软件项目中工作,其章程禁止使用专有构建依赖项),那么 GCJ(或其一些底层组件)可能是解决先有鸡还是先有蛋的问题的一种潜在解决方案,尽管启动 Java 的效率有些低,以便继续构建更理想的 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.

事实上,早在 OpenJDK 首次发布时,就花费了大量精力(通过 IcedTea 项目)来修复 GCJ,以使其能够完成任务。