TL; DR: Нужны лучшие тесты, лучшая настройка с контролем различий между выпусками и т. Д. Большинство проблем сравнительного анализа будет тривиально решаться с использованием JMH. Похоже, что текущее поведение теста объясняется сомнительным подходом к тестированию и изменением GC по умолчанию.
Учтите это:
public class PerformanceExperiment {
public static volatile String s = "";
public static void main(String[] args) {
for (int c = 0; c < 5; c++) {
test();
}
}
public static void test() {
String s1 = "STRING ONE";
String s2 = "STRING TWO";
long time1 = System.currentTimeMillis();
for (long i = 0; i < 4_000_000_00; i++) {
s = "abc " + s1 + " def " + s2;
}
long time2 = System.currentTimeMillis();
System.out.println("Main block took " + (time2 - time1) + "ms");
}
}
Во-первых, он использует более удобные тайминги. Затем он измеряет тот же самый блок байт-кода , в то время как исходные тесты нагревают «начальный», а затем приступают к измерению абсолютно холодного.
Затем JIT-компиляция попадет в метод, и вы захотите повторно ввести метод, чтобы запустить оптимизированный код, в противном случае вы запускаете промежуточный код «замена на стеке» - вы можете сделать это с внешним итерация, которая вызывает test
. И вдобавок ко всему, вы хотите ввести несколько раз, чтобы получить наиболее оптимизированную версию.
И, так как тест выделяет много, вы хотите прибить размер кучи.
Итак, вот:
$ ~/Install/jdk8u191-rh/bin/javac PerformanceExperiment.java
$ ~/Install/jdk8u191-rh/bin/java -Xms2g -Xmx2g PerformanceExperiment
Main block took 10024ms
Main block took 9768ms
Main block took 7249ms
Main block took 7235ms
Main block took 7205ms
... а вот 11.0.2 с тем же байт-кодом:
$ ~/Install/jdk11.0.2/bin/java -Xms2g -Xmx2g PerformanceExperiment
Main block took 9775ms
Main block took 10825ms
Main block took 8635ms
Main block took 8616ms
Main block took 8622ms
... а вот 11.0.2 с соответствующим GC (9+ изменил значение по умолчанию на G1 с JEP 248 ):
$ ~/Install/jdk11.0.2/bin/java -Xms2g -Xmx2g -XX:+UseParallelGC PerformanceExperiment
Main block took 9281ms
Main block took 9129ms
Main block took 6725ms
Main block took 6688ms
Main block took 6684ms
Кроме того, на каждой крошечной итерации есть магазин volatile
, который стоит довольно дорого и, вероятно, искажает эталонный тест.
Существует также взаимодействие с указанным конкататом строк (JEP 280) , локальными рукопожатиями (JEP 312) и другими исправлениями ВМ, но вы вероятно, увидит это только при компиляции прошлого target = 8, что выходит за рамки этого упражнения.