У меня есть следующие две программы:скорость Итерация междунар против длинного
long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
и
long startTime = System.currentTimeMillis();
for (long i = 0; i < N; i++);
long endTime = System.currentTimeMillis();
System.out.println("Elapsed time: " + (endTime - startTime) + " msecs");
Примечание: единственным отличием является тип переменной цикла (int
и long
).
Когда я запускаю это, первая программа последовательно печатает от 0 до 16 мс независимо от значения N
. Второй занимает намного больше времени. Для N == Integer.MAX_VALUE
он работает примерно на 1800 мсек на моей машине. Время работы кажется более или менее линейным в N
.
Так почему же это?
Я полагаю, JIT-компилятор оптимизирует цикл int
до смерти. И не зря, потому что явно ничего не делает. Но почему это не делается для цикла long
?
Коллега подумал, что мы можем измерить компилятор JIT, выполняющий его работу в цикле long
, но поскольку время работы кажется линейным в N
, это, вероятно, не так.
Я использую JDK 1.6.0 обновление 17:
C:\>java -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) 64-Bit Server VM (build 14.3-b01, mixed mode)
Я на Windows XP Professional x64 Edition с пакетом обновления 2 с процессором Intel Core2 Quad на 2,40 ГГц.
ОТКАЗ
Я знаю, что microbenchmarks не являются полезными в производстве. Я также знаю, что System.currentTimeMillis()
не так точна, как предполагает его название. Это то, что я заметил, обманывая, и мне было просто любопытно, почему это происходит; больше ничего.
Я абсолютно согласен с @Andrzej здесь, но если это на самом деле просто ради любопытства, вы можете использовать плагин PrintAssembly, чтобы действительно посмотреть на сгенерированный код: http://wikis.sun.com/display/HotSpotInternals/PrintAssembly –
Что произойдет, если вы используете флаг -Xint? Это предотвращает компиляцию Hotspot, поэтому вы получите лучшее сравнение. –
@Steven: но с '-Xint' результат * еще меньше * значим для всего, что похоже на реальное использование. –