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
6 ответов
GCJ устарел. Это было начато давно, потому что люди хотели альтернативу Sun JDK с открытым исходным кодом, и это никогда не было особенно хорошо. Теперь, когда Sun открыла исходный код своего JDK, нет абсолютно никакой причины использовать GCJ (но он все еще скрывается в некоторых дистрибутивах Linux).
Это несправедливое сравнение, когда вы выполняете компиляцию AOT (Ahead-Of-Time) с небольшой оптимизацией (-O). Попробуйте хотя бы -O2.
Это также не так просто, как один быстрее, чем другой в одном надуманном тесте. Компиляция AOT работает лучше всего в некоторых сценариях. JVM лучше работают в других, и это также сильно зависит от качества JVM. В реальном мире ecj заметно быстрее создает OpenJDK при компиляции AOT, а не при работе на JVM. Для долгосрочных приложений JVM, вероятно, победит, потому что он может использовать динамическую оптимизацию, которая невозможна раньше времени. ecj страдает, потому что за короткий период его компиляции JVM все еще интерпретирует код. HotSpot компилирует и оптимизирует код, когда он определяет его ценность ("горячая точка").
Кстати, это FAQ, который устарел. 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.
Собственный Java-компилятор OpenJDK написан на Java; как следствие, вам нужна рабочая предыдущая версия Java для создания новой версии.
Если вы начинаете с нуля на платформе, для которой нет доступных готовых двоичных файлов JDK (или если вы работаете в рамках определенных проектов свободного программного обеспечения, чьи уставы запрещают использование зависимостей собственной сборки), то GCJ (или некоторые из лежащих в его основе компоненты) могут быть одним из потенциальных решений проблемы "взломать и взбодриться", заключающейся в создании работающей, хотя и несколько неэффективной, начальной загрузки Java, для того, чтобы перейти к созданию более желательного OpenJDK.
На самом деле, когда был впервые анонсирован OpenJDK, значительные усилия (через проект IcedTea) были потрачены на исправление GCJ, чтобы довести его до того уровня, когда оно было выполнено.
"Итак, какова цель GCJ тогда?"
Некоторые указали, что ваш "эталон" не справедлива. Тем не менее, даже если бы это было так, я все еще вижу использование GCJ. Предположим, вы хотите написать ядро на Java. С помощью JVM вы должны портировать виртуальную машину в автономную среду, а затем вам нужно будет написать код низкого уровня на языке C. С помощью компилятора AOT вы можете обойти эту проблему с помощью некоторого связующего кода, а затем выполнить низкий код. Уровень кода в Java тоже. Нет необходимости портировать компилятор в этом случае.
Кроме того, мы должны отделить технику от тестов. Возможно, метод AOT может быть более мощным, чем метод JIT, при условии, что мы вложим в него достаточно усилий для разработки.
Вы наткнулись на другой продукт "Software Freedom любой ценой!" мышление. GCJ был создан, чтобы позволить компиляцию и выполнение кода Java без зависимости от того, что GNU-проект считает "несвободным".
Если вы цените свободу программного обеспечения настолько, чтобы получить 12-кратный удар по производительности, тогда обязательно делайте это!
Остальные из нас с радостью будут использовать невероятную виртуальную машину HotSpot от Sun (или Oracle).
Также: "Он был объединен с GNU Classpath и поддерживает большинство библиотек 1.4 плюс некоторые дополнения 1.5". Так что это немного устарело.