Почему «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++ участвует в сравнении значений.

Ответы на вопрос(5)

Ваш ответ на вопрос