Wie schreibe ich einen korrekten Mikro-Benchmark in Java?
Wie du schreibst (und ausführen) eine richtige micro-benchmark in Java?
Ich bin auf der Suche hier für code-Beispiele und Bemerkungen illustrieren verschiedene Dinge zu denken.
Beispiel: Sollte der benchmark-Messung von Zeit/iteration oder Iterationen/Zeit, und warum?
Verwandte: Ist die Stoppuhr benchmarking akzeptabel?
InformationsquelleAutor der Frage John Nilsson | 2009-02-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Tipps zum schreiben von micro-benchmarks von den Machern von Java-HotSpot:
Regel 0: Lesen einem seriösen Papier auf JVMs und micro-benchmarking. Ein guter ist Brian Goetz, 2005. Erwarten Sie nicht zu viel von micro-benchmarks; Sie Messen nur eine begrenzte Anzahl von JVM-performance-Merkmale.
Regel 1: Immer auch ein warm-up phase läuft Ihr test-kernel, den ganzen Weg durch, genug, um die trigger-alle Initialisierungen und compilations, bevor die timing-phase(s). (Weniger Iterationen ist OK, auf der warmup-phase. Die Faustregel ist, mehrere Zehntausende von inneren schleifendurchläufe.)
Regel 2: laufen Immer mit
-XX:+PrintCompilation
-verbose:gc
usw., so können Sie sicherstellen, dass der compiler und andere Teile der JVM sind nicht dabei unerwartete Arbeit während der timing-phase.Regel 2.1: Drucken, Nachrichten an den Anfang und das Ende-timing-und-warm-up-Phasen, so dass Sie überprüfen können, dass es keine Ausgabe von Regel 2 während der timing-phase.
Regel 3: sich bewusst Sein, der Unterschied zwischen -client und -server, und OSR und fortlaufenden Sammelwerken. Die
-XX:+PrintCompilation
flag-Berichte OSR-Zusammenstellungen mit einem at-Zeichen zu Kennzeichnen die nicht-Initiale Einstiegspunkt, zum Beispiel:Trouble$1::run @ 2 (41 bytes)
. Lieber server, client, und regelmäßige, OSR, wenn Sie nach der besten performance.Regel 4: bewusst Sein, Initialisierung Effekte. Nicht das erste mal drucken, während Sie Ihr timing, phase, da sich das drucken und lädt und initialisiert Klassen. Laden Sie keine neuen Klassen außerhalb der warmup-phase (oder finalen reporting phase), es sei denn, Sie werden die Prüfung der Klasse be-insbesondere (und in diesem Fall laden Sie nur die test-Klassen). Regel 2 ist Ihre erste Linie der Verteidigung gegen solche Effekte.
Regel 5: bewusst Sein, deoptimization und Neukompilierung Effekte. Nehmen Sie keine code-Pfad für die erste Zeit, in der timing-phase, denn der compiler kann die junk-und kompilieren Sie den code, basierend auf einem früheren optimistischen Annahme, dass der Pfad wurde nicht benutzt werden. Regel 2 ist Ihre erste Linie der Verteidigung gegen solche Effekte.
Regel 6: Verwenden Sie geeignete Werkzeuge zum Lesen der compiler ist der Meinung, und erwarten Sie, überrascht zu sein von dem code, den es produziert. Untersuchen Sie den code selbst, bevor er Theorien über das, was etwas schneller oder langsamer.
Regel 7: Reduzieren Sie Rauschen in den Messungen. Führen Sie Ihre benchmark auf eine ruhige Maschine, und führen Sie es mehrmals, verwerfen von Ausreißern. Verwenden
-Xbatch
zu serialisieren Sie den compiler mit der Anwendung, und ziehen Sie in Betracht-XX:CICompilerCount=1
um zu verhindern, dass der compiler ausgeführt wird, parallel mit sich selbst.Regel 8: Nutzen Sie die Bibliothek für Ihre benchmark, da ist es wahrscheinlich effizienter und wurde schon ausgetestet, die zu diesem Zweck. Wie JMHBremssattel oder Bill-und-Pauls-Exzellente UCSD-Benchmarks für Java.
InformationsquelleAutor der Antwort
Ich weiß, diese Frage wurde markiert als beantwortet, aber ich wollte zu erwähnen, zwei Bibliotheken, die es uns ermöglichen, schreiben die micro-benchmarks
Bremssattel von Google
Erste Schritte-tutorials
JMH von OpenJDK
Erste Schritte-tutorials
InformationsquelleAutor der Antwort Aravind R. Yarram
Wichtige Dinge für Java-benchmarks sind:
System.gc()
zwischen Iterationen, ist es eine gute Idee, um Sie zwischen den tests, so dass jeder test, der hoffentlich bekommen die einen "sauberen" Speicher, mit zu arbeiten. (Ja,gc()
ist mehr ein Hinweis als eine Garantie, aber es ist sehr wahrscheinlichdass es wirklich Müll sammeln, in meiner Erfahrung.)Bin ich nur in den Prozess der das Bloggen über die Gestaltung eines benchmarking-Rahmen .NET. Ich habe eine paar von frühere Beiträgedie möglicherweise in der Lage sein, um Ihnen einige Anregungen geben - nicht alles wird geeignet sein, natürlich, aber einige kann es sein.
InformationsquelleAutor der Antwort Jon Skeet
jmh ist eine aktuelle Ergänzung zu OpenJDK und geschrieben wurde von einigen Ingenieuren performance von Oracle. Sicherlich lohnt sich einen Blick.
Sehr interessante Stücke von Informationen begraben in die Probe tests, Kommentare.
Siehe auch:
InformationsquelleAutor der Antwort assylias
Es hängt davon ab, was Sie versuchen, zu testen. Wenn Sie daran interessiert sind, Latenz, verwenden Sie Zeit/iteration und wenn Sie daran interessiert sind, den Durchsatz verwenden Iterationen/Zeit.
InformationsquelleAutor der Antwort Peter Lawrey
Stellen Sie sicher, dass Sie irgendwie verwenden die Ergebnisse, die berechnet werden, die im Benchmark-code. Ansonsten kann der code optimiert werden entfernt.
InformationsquelleAutor der Antwort Peter Štibraný
Wenn Sie versuchen, zu vergleichen zwei algorithmen, mindestens zwei benchmarks auf den einzelnen, im Wechsel der Reihenfolge. also:
Habe ich gefunden einige deutliche Unterschiede (5-10% manchmal) in der Laufzeit der gleiche Algorithmus in verschiedenen Durchläufen..
Stellen Sie außerdem sicher, dass n ist sehr groß, so dass die Laufzeit der einzelnen Schleifen ist zumindest 10 Sekunden oder so. Je mehr Iterationen, desto mehr bedeutende Persönlichkeiten, die in Ihrem benchmark-Zeit und zuverlässiger Daten.
InformationsquelleAutor der Antwort Kip
Gibt es viele mögliche Fallstricke für das schreiben von micro-benchmarks in Java.
Erstens: Sie haben zu berechnen, die alle möglichen Ereignisse, die Zeit nehmen, mehr oder weniger zufällig: Garbage collection, Cache-Effekte (von OS nach Dateien und CPU-Speicher), IO etc.
Zweite: Sie nicht Vertrauen können, die Genauigkeit der gemessenen Zeiten für sehr kurze Intervalle.
Drittens: Die JVM optimiert Ihren code während der Ausführung. So unterschiedlich läuft in der gleichen JVM-Instanz wird immer schneller und schneller.
Meine Empfehlungen: Machen Sie Ihre benchmark laufen ein paar Sekunden, das ist zuverlässiger als eine Laufzeit über Millisekunden. Warm-up für die JVM (ausführen der benchmark mindestens einmal ohne Messung, dass der JVM ausgeführt werden kann-Optimierungen). Und führen Sie Ihre benchmark mehrere Male (vielleicht 5 mal) und nehmen den median-Wert. Führen Sie jede micro-benchmark in eine neue JVM-Instanz (nennen Sie für jeden benchmark neue Java -) ansonsten-Optimierung Auswirkungen der JVM beeinflussen kann später ausführen von tests. Nicht ausführen Dinge, die werden nicht ausgeführt, in der warmup-phase (dies könnte trigger-Klasse-laden und Neukompilierung).
InformationsquelleAutor der Antwort Mnementh
Es sollte auch darauf hingewiesen werden, dass es vielleicht auch wichtig sein, zu analysieren, die Ergebnisse der micro-benchmark beim Vergleich verschiedener Implementierungen. Daher Signifikanz-test gemacht werden sollte.
Dies ist, weil die Umsetzung
A
könnte schneller sein, bei den meisten läuft der benchmark als UmsetzungB
. AberA
könnte auch ein höherer spread, also die gemessene Leistung vonA
nicht von Bedeutung, wenn im Vergleich mitB
.So ist es auch wichtig, zu schreiben und führen Sie eine micro-benchmark korrekt, aber auch, um es richtig zu analysieren.
InformationsquelleAutor der Antwort SpaceTrucker
http://opt.sourceforge.net/ Java-Micro-Benchmark - control-Aufgaben erforderlich, um festzustellen, vergleichende performance-Merkmale der computer-system auf verschiedenen Plattformen. Kann verwendet werden, um die guide-Optimierung Entscheidungen und Vergleiche zwischen verschiedenen Java-Implementierungen.
InformationsquelleAutor der Antwort Yuriy
Hinzufügen, um den anderen gute Ratschläge, ich würde auch darauf achten, die folgenden:
Für einige CPUs (z.B. Intel Core i5-Reihe, mit TurboBoost), der Temperatur (und die Anzahl der Kerne, die derzeit verwendet wird, als auch thier-Nutzung Prozent) wirkt sich auf die Geschwindigkeit. Da die CPU dynamisch getaktet wird, kann dies Auswirkungen auf Ihre Ergebnisse. Zum Beispiel, wenn Sie eine single-threaded-Anwendung, die maximale Taktrate (mit TurboBoost) ist höher als für eine Anwendung mit allen Kernen. Deshalb kann es stören Vergleiche von Einzel-und multi-threaded-performance auf einigen Systemen. Beachten Sie, dass die Temperatur und volatages auch beeinflussen, wie lange Turbo-Frequenz beibehalten wird.
Vielleicht ein grundlegend wichtiger Aspekt, dass Sie die direkte Kontrolle über: stellen Sie sicher, dass die Messung das richtige für Sie! Zum Beispiel, wenn Sie
System.nanoTime()
benchmark einer bestimmten bit-code, legen Sie die Anrufe auf die Abtretung an Orten, die Sinn machen, zu vermeiden, Dinge zu Messen, die Sie nicht interessieren. Zum Beispiel sollten Sie nicht tun:Problem ist, du bist nicht sofort immer am Ende der Zeit, wenn der code fertig ist. Versuchen Sie stattdessen Folgendes:
InformationsquelleAutor der Antwort Sina Madani