Ich habe einige Leistungstests bezüglich der Objektzuordnung durchgeführt, als ich auf ein komisches Ergebnis stieß. Ich habe den folgenden Java-Code:Java: Was verursacht die Leistungssteigerung beim wiederholten Aufruf einer Funktion?
public static long TestMethod(){
int len = 10000000;
Object[] obs = new Object[len];
long t = System.nanoTime();
for (int i = 0; i < len; i++) {
obs[i] = new Object();
}
return System.nanoTime() - t;
}
public static void main(String... args) throws InterruptedException {
for(int i = 0; i < 10; i++){
System.gc();
System.gc();//Wait for the gc to be finished
Thread.sleep(1000);
System.out.println(TestMethod());
}
}
Erwartung: Erster Aufruf langsamer sein wird, dann zweiten Anruf aufgrund eines größeren Speicherraum von dem Betriebssystem und Hotspot-Erweiterungen anfordert. Aber der zweite und der dritte werden fast gleich sein.
Beobachtete Ergebnis:
11284734000
799837000
682304000
304736000
380770000
392786000
374279000
381611000
379174000
407256000
noch eine beträchtliche Beschleunigung zwischen der dritten und vierten Iteration. Was verursacht diese Beschleunigung? Wie kann ich beim Testen anderer Funktionen sicher sein, dass meine Messungen genau sind? Muss ich die Funktion mehr als vier Mal aufrufen, bevor ich Messungen durchführe?
[Just-in-Time-Compiler Startverzögerung] (http://en.wikipedia.org/wiki/Just-in-time_compilation#Startup_delay_and_optimizations) –
interessant zu lesen: http://stackoverflow.com/questions/504103/how-do-ich-schreibe-a-correct-micro-benchmark-in-java - Insbesondere das Ausführen mit den VM-Parametern "-XX: + PrintCompilation -verbose: gc" hilft dir zu verstehen, was vor sich geht. – assylias
@assylias: Interessant. Kannte diese Parameter nicht. Es scheint, die Funktion in dem zweiten Aufruf neu zu kompilieren und 2 Garbage Collections in den ersten drei Aufrufen und den letzten Aufrufen auszuführen, die keine Speicherbereinigung in den Funktionsaufrufen vornehmen. – user23127