Остерегайтесь опасностей микро-бенчмаркинга !!!
Я взял код, обернул метод вокруг и выполнил это 10 раз в цикле.Результаты:
50, 3,
3, 0,
0, 0,
0, 0,
....
Без некоторого реального кода в циклах компиляторы могут выяснить, что циклы не выполняют никакой полезной работы, и полностью их оптимизировать.Учитывая измеренную производительность, я подозреваю, что эта оптимизация могла быть сделана javac
.
Урок 1. Компиляторы часто оптимизируют код, который выполняет бесполезную «работу».Чем умнее компилятор, тем больше вероятность того, что такого рода вещи произойдут.Если вы не учитываете это при кодировании, эталонный тест может быть бессмысленным.
Поэтому я добавил следующее простое вычисление в оба цикла if (i < 2 * j) longK++;
и заставил тестовый метод вернуть окончательное значениеlongK
.Результаты:
32267, 33382,
34542, 30136,
12893, 12900,
12897, 12889,
12904, 12891,
12880, 12891,
....
Мы явно остановили компиляторы, оптимизирующие цикл.Но теперь мы видим эффекты разогрева JVM в (в данном случае) первых двух парах итераций цикла.Первые две пары итераций (один вызов метода), вероятно, выполняются исключительно в интерпретируемом режиме.И, похоже, третья итерация может работать параллельно с JIT.По третьей паре итераций мы, скорее всего, запускаем чистый нативный код.И с тех пор разница между временными интервалами двух версий цикла - просто шум.
Урок 2: всегда учитывайте эффект разогрева JVM.Это может серьезно исказить результаты тестов, как микро, так и макро.
Вывод - после разогрева JVM между двумя версиями цикла нет ощутимой разницы.