Tipps zum Schreiben von Mikro-Benchmarks von den Entwicklern von Java HotSpot :
Regel 0: Lesen Sie ein seriöses Papier über JVMs und Mikro-Benchmarking. Ein guter ist Brian Goetz, 2005 . Erwarten Sie nicht zu viel von Mikro-Benchmarks. Sie messen nur einen begrenzten Bereich von JVM-Leistungsmerkmalen.
Regel 1: Schließen Sie immer eine Aufwärmphase ein, in der Ihr Testkernel vollständig ausgeführt wird, sodass alle Initialisierungen und Kompilierungen vor der Timing-Phase (n) ausgelöst werden. (In der Aufwärmphase sind weniger Iterationen in Ordnung. Als Faustregel gelten mehrere Zehntausend Iterationen der inneren Schleife.)
Regel 2: Immer lief mit -XX:+PrintCompilation
, -verbose:gc
etc., so dass Sie überprüfen können , dass der Compiler und andere Teile der JVM sind nicht unerwartet Arbeit während Taktphase zu tun.
Regel 2.1: Drucken Sie Nachrichten zu Beginn und am Ende der Timing- und Aufwärmphase, damit Sie überprüfen können, ob während der Timing-Phase keine Ausgabe von Regel 2 erfolgt.
Regel 3: Beachten Sie den Unterschied zwischen -client
und -server
, OSR und regelmäßigen Zusammenstellungen. Das -XX:+PrintCompilation
Flag meldet OSR-Kompilierungen mit einem At-Zeichen, um den nicht anfänglichen Einstiegspunkt zu kennzeichnen, zum Beispiel : Trouble$1::run @ 2 (41 bytes)
. Bevorzugen Sie Server gegenüber Client und regulär gegenüber OSR, wenn Sie die beste Leistung erzielen möchten.
Regel 4: Beachten Sie die Initialisierungseffekte. Drucken Sie während Ihrer Timing-Phase nicht zum ersten Mal, da beim Drucken Klassen geladen und initialisiert werden. Laden Sie keine neuen Klassen außerhalb der Aufwärmphase (oder der letzten Berichtsphase), es sei denn, Sie testen das Laden von Klassen speziell (und laden in diesem Fall nur die Testklassen). Regel 2 ist Ihre erste Verteidigungslinie gegen solche Effekte.
Regel 5: Achten Sie auf Deoptimierungs- und Neukompilierungseffekte. Nehmen Sie zum ersten Mal in der Timing-Phase keinen Codepfad, da der Compiler den Code möglicherweise verschmutzen und neu kompilieren kann, basierend auf einer früheren optimistischen Annahme, dass der Pfad überhaupt nicht verwendet werden würde. Regel 2 ist Ihre erste Verteidigungslinie gegen solche Effekte.
Regel 6: Verwenden Sie geeignete Tools, um die Gedanken des Compilers zu lesen, und lassen Sie sich von dem von ihm erzeugten Code überraschen. Überprüfen Sie den Code selbst, bevor Sie Theorien darüber aufstellen, was etwas schneller oder langsamer macht.
Regel 7: Reduzieren Sie das Rauschen bei Ihren Messungen. Führen Sie Ihren Benchmark auf einem leisen Computer aus und führen Sie ihn mehrmals aus, wobei Sie Ausreißer verwerfen. Verwenden Sie -Xbatch
diese Option, um den Compiler mit der Anwendung zu serialisieren, und erwägen Sie die Einstellung -XX:CICompilerCount=1
, um zu verhindern, dass der Compiler parallel zu sich selbst ausgeführt wird. Versuchen Sie nach besten Kräften, den GC-Overhead zu reduzieren, setzen Sie Xmx
(groß genug) gleich Xms
und verwenden Sie ihn, UseEpsilonGC
falls verfügbar.
Regel 8: Verwenden Sie eine Bibliothek für Ihren Benchmark, da diese wahrscheinlich effizienter ist und bereits zu diesem alleinigen Zweck getestet wurde. Wie JMH , Caliper oder Bill und Pauls ausgezeichnete UCSD-Benchmarks für Java .