Почему «while (i ++ <n) {}» значительно медленнее, чем «while (++ i <n) {}»
Очевидно на моем ноутбуке с 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 шага в обратном порядке. Но это, кажется, не объясняет, почему первый намного быстрее. Есть ли временная копия в последнем случае? Или что-то помимо байт-кода (реализация виртуальной машины, оборудование и т. Д.) Должно отвечать за разницу в производительности?
Я прочитал некоторые другие обсуждения, касающиеся++i
а такжеi++
(хотя и не исчерпывающе), но не нашел ответа, специфичного для Java и напрямую связанного со случаем, когда++i
или жеi++
участвует в сравнении значений.