Ich habe einige Tests durchgeführt, um herauszufinden, was die Geschwindigkeitsunterschiede zwischen Getter/Setter und direktem Feldzugriff sind. Ich schrieb eine einfache Benchmark-Anwendung wie folgt aus:Warum erscheint der Methodenzugriff schneller als der Feldzugriff?
public class FieldTest {
private int value = 0;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
public static void doTest(int num) {
FieldTest f = new FieldTest();
// test direct field access
long start1 = System.nanoTime();
for (int i = 0; i < num; i++) {
f.value = f.value + 1;
}
f.value = 0;
long diff1 = System.nanoTime() - start1;
// test method field access
long start2 = System.nanoTime();
for (int i = 0; i < num; i++) {
f.setValue(f.getValue() + 1);
}
f.setValue(0);
long diff2 = System.nanoTime() - start2;
// print results
System.out.printf("Field Access: %d ns\n", diff1);
System.out.printf("Method Access: %d ns\n", diff2);
System.out.println();
}
public static void main(String[] args) throws InterruptedException {
int num = 2147483647;
// wait for the VM to warm up
Thread.sleep(1000);
for (int i = 0; i < 10; i++) {
doTest(num);
}
}
}
Jedes Mal, wenn ich es laufen, ich konsistente Ergebnisse wie diese bekommen: http://pastebin.com/hcAtjVCL
Ich frage mich, ob mir jemand erklären könnte, warum Feld Zugang scheint langsamer zu sein als Getter/Setter-Methode Zugriff, und auch, warum die letzten 8 Iterationen unglaublich schnell ausführen.
bearbeiten: Nachdem assylias
und Stephen C
Kommentare berücksichtigt, ich habe den Code http://pastebin.com/Vzb8hGdc geändert, wo ich etwas andere Ergebnisse erhielt: http://pastebin.com/wxiDdRix.
Ich denke, der Compiler inline die Getter sowieso. Hast du den Bytecode überprüft? – jlordo
'/ * warte auf das Aufwärmen der VM */Thread.sleep (1000);' - so funktioniert es nicht. Die JVM wird nicht warm, wenn es nichts tut ... Ihr Mikro-Benchmark hat mehrere Fehler. Insbesondere: (i) Sie erlauben der JVM nicht wirklich, sich aufzuwärmen. (Ii) Die beiden Pfade, die Sie testen möchten, sind in der gleichen Methode, was einige Optimierungen verhindern könnte. – assylias
@jlordo - das Inlining erfolgt durch den JIT-Compiler. Ich werde in den Bytecodes nicht offensichtlich sein. –