Java JRE与GCJ
我用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
GCJ已经过时了。 它是很久以前开始的,因为人们想要一个开源替代Sun JDK,它从来没有特别好。 既然Sun公开了他们的JDK,那么绝对没有理由使用GCJ(但它仍然潜伏在一些Linux发行版中)。
当您使用少量优化(-O)进行AOT(Ahead-Of-Time)编译时,这不是一个公平的比较。 至少尝试-O2。
在一个人为的测试中,它也不像一个人那么简单。 AOT编译在某些情况下效果最佳。 JVM在其他方面运行得更好,而且在很大程度上还取决于JVM的质量。 在现实世界中,当AOT编译而不是在JVM上运行时,ecj在构建OpenJDK方面明显更快。 对于长期运行的应用程序,JVM很可能会获胜,因为它可以利用事先不可能的动态优化。 ecj受到影响,因为在短时间内它正在编译,JVM仍在解释代码。 HotSpot在确定代码值时(“热点”)编译并优化代码。
顺便说一句,这是过时的常见问题解答。 GCJ支持1.5的大部分,当然足以构建OpenJDK。 如果GCJ仍然“潜伏在某些Linux发行版中”,那么首先不可能构建OpenJDK。
在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算法。
OpenJDK的本机Java编译器本身是用Java编写的; 因此,您需要一个可用的以前版本的Java才能构建新版本。
如果你是在一个没有现有JDK二进制文件的平台上从头开始(或者如果你在其章程禁止使用专有构建依赖项的某些自由软件项目中工作),那么GCJ(或其某些基础知识)组件)可以成为鸡和鸡蛋问题的一个潜在解决方案,以获得一个有效的,虽然有点低效的引导程序Java,以便继续构建更理想的OpenJDK。
事实上,当OpenJDK首次公布时,我已经花费了很多精力(通过IcedTea项目)来修复GCJ以使其达到完成任务的程度。
“那么,GCJ的目的是什么呢?”
有人指出你的“基准”不公平。 然而,即使它是,我仍然可以看到GCJ的用途。 假设您想用Java编写内核。 使用JVM,您必须将VM移植到独立环境,然后您必须在C中编写低杠杆代码。使用AOT编译器,您可以使用一些粘合代码解决此问题然后可以执行低Java中的级别代码也是如此。 在这种情况下无需移植编译器。
此外,我们必须将技术与基准分开。 也许AOT技术可以比JIT技术更强大,前提是我们在其中投入了足够的开发工作。
你不惜一切代价偶然发现了“软件自由”的另一款产品! 思路。 GCJ的创建是为了允许编译和执行Java代码,而不依赖于GNU项目认为“非自由”的任何东西。
如果你重视软件自由度足以达到12倍的性能,那么无论如何都要去吧!
我们其他人将很乐意使用Sun的(呃,甲骨文)令人难以置信的HotSpot JVM。
另请参阅: GCJ常见问题解答:“我刚刚编译并对我的Java应用程序进行了基准测试,它似乎比XXX JIT JVM运行速度慢。我能做些什么来让它更快?”
另外:“它已经与GNU Classpath合并,支持大多数1.4库以及1.5个新增function。” 所以它也有点过时了。