По-видимому, на моем ноутбуке Windows 8 с HotSpot JDK 1.7.0_45 (при всех параметрах компилятора/виртуальной машины по умолчанию) нижний цикл
final int n = Integer.MAX_VALUE;
int i = 0;
while (++i < n) {
}
не менее чем на 2 порядка быстрее (~ 10 мс против ~ 5000 мс), чем:
final int n = Integer.MAX_VALUE;
int i = 0;
while (i++ < n) {
}
Мне приходилось замечать эту проблему при написании цикла для оценки другой нерелевантной проблемы производительности. И разница между ++i < n
и i++ < n
была достаточно огромной, чтобы существенно повлиять на результат.
Если мы посмотрим на байт-код, тело цикла более быстрой версии:
iinc
iload
ldc
if_icmplt
И для более медленной версии:
iload
iinc
ldc
if_icmplt
Итак, для ++i < n
он сначала увеличивает локальную переменную i
на 1, а затем нажимает ее на стек операнда, а i++ < n
выполняет эти 2 шага в обратном порядке. Но это, похоже, не объясняет, почему первое намного быстрее. Есть ли временная копия в последнем случае? Или это что-то помимо байт-кода (внедрение VM, аппаратное обеспечение и т.д.), Которые должны отвечать за разницу в производительности?
Я прочитал некоторое другое обсуждение относительно ++i
и i++
(но не исчерпывающе), но не нашел ответа, специфичного для Java, и непосредственно связанного с случаем, когда ++i
или i++
участвует в сравнении значений.