Остерегайтесь опасностей микробенчмаркинга !!!
Я взял код, обернул метод снаружи и запустил его 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 разогревается, между двумя версиями цикла нет заметной разницы.
person
Stephen C
schedule
07.05.2010