Warum ist "while (i ++ <n) {}" wesentlich langsamer als "while (++ i <n) {}"?
Anscheinend auf meinem Windows 8-Laptop mit HotSpot JDK 1.7.0_45 (mit allen Compiler / VM-Optionen auf Standard gesetzt), die folgende Schleife
final int n = Integer.MAX_VALUE;
int i = 0;
while (++i < n) {
}
ist mindestens 2 Größenordnungen schneller (~ 10 ms gegenüber ~ 5000 ms) als:
final int n = Integer.MAX_VALUE;
int i = 0;
while (i++ < n) {
}
Ich bemerkte dieses Problem beim Schreiben einer Schleife, um ein anderes irrelevantes Leistungsproblem zu bewerten. Und der Unterschied zwischen++i < n
undi++ < n
war groß genug, um das Ergebnis maßgeblich zu beeinflussen.
Wenn wir uns den Bytecode ansehen, ist der Schleifenkörper der schnelleren Version:
iinc
iload
ldc
if_icmplt
Und für die langsamere Version:
iload
iinc
ldc
if_icmplt
So für++i < n
, erhöht es zuerst die lokale Variablei
um 1 und schieben Sie es dann auf den Operandenstapel, währendi++ < n
macht diese 2 Schritte in umgekehrter Reihenfolge. Aber das scheint nicht zu erklären, warum Ersteres viel schneller ist. Ist im letzteren Fall eine temporäre Kopie beteiligt? Oder sollte etwas jenseits des Bytecodes (VM-Implementierung, Hardware usw.) für den Leistungsunterschied verantwortlich sein?
Ich habe eine andere Diskussion über gelesen++i
undi++
(nicht erschöpfend), aber keine Antwort gefunden, die Java-spezifisch ist und direkt mit dem Fall zusammenhängt, in dem++i
oderi++
ist an einem Wertevergleich beteiligt.