23

我从用 Java 编写的速度测试中得到了这个结果:

Java

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

GCJ

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

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

我在 Linux 上对此进行了测试,Windows 中的结果可能比这更好吗?

这是来自应用程序的代码:

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!!!");
}

我用 GCJ 编译是这样的:

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

并像这样跑:

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

6 回答 6

36

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

于 2010-06-13T15:25:21.177 回答
14

当您执行 AOT(Ahead-Of-Time)编译而几乎没有优化 (-O) 时,这不是一个公平的比较。至少尝试-O2。

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

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

于 2010-06-14T15:37:34.917 回答
9

在 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

这样就可以解释速度差异。

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

于 2011-02-24T14:23:15.330 回答
5

OpenJDK 的原生 Java 编译器本身是用 Java 编写的;因此,您需要使用 Java 的早期版本才能构建新版本。

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

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

于 2013-11-13T16:43:46.790 回答
2

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

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

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

于 2012-02-23T14:11:56.947 回答
1

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

如果您对软件自由的重视程度足以承受 12 倍的性能冲击,那么一定要争取!

我们其他人会很乐意使用 Sun(呃,Oracle)令人难以置信的 HotSpot JVM。

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

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

于 2010-06-13T15:24:15.060 回答