Benchmarkdotnet hilft Ihnen, Methoden in Benchmarks umzuwandeln, ihre Leistung zu verfolgen und reproduzierbare Messungsexperimente zu teilen. Es ist nicht schwieriger als das Schreiben von Unit -Tests! Unter der Motorhaube führt es eine Menge Magie aus, die dank der statistischen Perfolizer -Motor zuverlässige und genaue Ergebnisse garantiert. Benchmarkdotnet schützt Sie vor beliebten Benchmarking -Fehlern und warnt Sie, wenn Ihr Benchmark -Design oder mit erhaltenen Messungen etwas nicht stimmt. Die Ergebnisse werden in einer benutzerfreundlichen Form dargestellt, die alle wichtigen Fakten über Ihr Experiment hervorhebt. Benchmarkdotnet wird bereits von 22000 Github -Projekten übernommen, darunter .NET RunTime, .NET Compiler, .NET Performance und viele andere.
Es ist einfach, Benchmarks zu schreiben. Schauen Sie sich das folgende Beispiel an (kopierbare Version ist hier):
[ SimpleJob ( RuntimeMoniker . Net472 , baseline : true ) ]
[ SimpleJob ( RuntimeMoniker . NetCoreApp30 ) ]
[ SimpleJob ( RuntimeMoniker . NativeAot70 ) ]
[ SimpleJob ( RuntimeMoniker . Mono ) ]
[ RPlotExporter ]
public class Md5VsSha256
{
private SHA256 sha256 = SHA256 . Create ( ) ;
private MD5 md5 = MD5 . Create ( ) ;
private byte [ ] data ;
[ Params ( 1000 , 10000 ) ]
public int N ;
[ GlobalSetup ]
public void Setup ( )
{
data = new byte [ N ] ;
new Random ( 42 ) . NextBytes ( data ) ;
}
[ Benchmark ]
public byte [ ] Sha256 ( ) => sha256 . ComputeHash ( data ) ;
[ Benchmark ]
public byte [ ] Md5 ( ) => md5 . ComputeHash ( data ) ;
}Benchmarkdotnet führt die Benchmarks automatisch auf allen Laufzeiten aus, aggregiert die Messungen und druckt eine Zusammenfassungstabelle mit den wichtigsten Informationen:
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.17763.805 (1809/October2018Update/Redstone5)
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
[ Host ] : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
Net472 : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
NetCoreApp30 : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
NativeAot70 : .NET 7.0.0-preview.4.22172.7, X64 NativeAOT
Mono : Mono 6.4.0 (Visual Studio), X64
| Method | Runtime | N | Mean | Error | StdDev | Ratio |
| ------- | -------------- | ------ | -----------: | ----------: | ----------: | ------: |
| Sha256 | .NET 4.7.2 | 1000 | 7.735 us | 0.1913 us | 0.4034 us | 1.00 |
| Sha256 | .NET Core 3.0 | 1000 | 3.989 us | 0.0796 us | 0.0745 us | 0.50 |
| Sha256 | NativeAOT 7.0 | 1000 | 4.091 us | 0.0811 us | 0.1562 us | 0.53 |
| Sha256 | Mono | 1000 | 13.117 us | 0.2485 us | 0.5019 us | 1.70 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 1000 | 2.872 us | 0.0552 us | 0.0737 us | 1.00 |
| Md5 | .NET Core 3.0 | 1000 | 1.848 us | 0.0348 us | 0.0326 us | 0.64 |
| Md5 | NativeAOT 7.0 | 1000 | 1.817 us | 0.0359 us | 0.0427 us | 0.63 |
| Md5 | Mono | 1000 | 3.574 us | 0.0678 us | 0.0753 us | 1.24 |
| | | | | | | |
| Sha256 | .NET 4.7.2 | 10000 | 74.509 us | 1.5787 us | 4.6052 us | 1.00 |
| Sha256 | .NET Core 3.0 | 10000 | 36.049 us | 0.7151 us | 1.0025 us | 0.49 |
| Sha256 | NativeAOT 7.0 | 10000 | 36.253 us | 0.7076 us | 0.7571 us | 0.49 |
| Sha256 | Mono | 10000 | 116.350 us | 2.2555 us | 3.0110 us | 1.58 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 10000 | 17.308 us | 0.3361 us | 0.4250 us | 1.00 |
| Md5 | .NET Core 3.0 | 10000 | 15.726 us | 0.2064 us | 0.1930 us | 0.90 |
| Md5 | NativeAOT 7.0 | 10000 | 15.627 us | 0.2631 us | 0.2461 us | 0.89 |
| Md5 | Mono | 10000 | 30.205 us | 0.5868 us | 0.6522 us | 1.74 |
Die gemessenen Daten können in verschiedene Formate (MD, HTML, CSV, XML, JSON usw.) einschließlich der Diagramme exportiert werden:
Unterstützte Laufzeiten: .NET 5+, .NET Framework 4.6.1+, .NET Core 3.1+, Mono, Nativeaot
Unterstützte Sprachen: C#, f#, visual grundlegend
Unterstütztes Betriebssystem: Windows, Linux, macOS
Unterstützte Architekturen: x86, x64, Arm, ARM64, WASM und Loongarch64
Benchmarkdotnet verfügt über unzählige Funktionen, die für umfassende Leistungsuntersuchungen von wesentlicher Bedeutung sind. Vier Aspekte definieren das Design dieser Funktionen: Einfachheit , Automatisierung , Zuverlässigkeit und Freundlichkeit .
Sie sollten kein erfahrener Performance -Ingenieur sein müssen, wenn Sie Benchmarks schreiben möchten. Sie können sehr komplizierte Leistungsexperimente im deklarativen Stil mit einfachen APIs entwerfen.
Wenn Sie beispielsweise Ihren Benchmark parametrisieren möchten, markieren Sie ein Feld oder eine Eigenschaft mit [Params(1, 2, 3)] : BenchmarkdotNet wird alle angegebenen Werte aufzählt und für jeden Fall Benchmarks ausführen. Wenn Sie Benchmarks miteinander vergleichen möchten, markieren Sie eines der Benchmarks als Basislinie über [Benchmark(Baseline = true)] : Benchmarkdotnet wird es mit allen anderen Benchmarks vergleichen. Wenn Sie die Leistung in verschiedenen Umgebungen vergleichen möchten, verwenden Sie Jobs. Sie können beispielsweise alle Benchmarks auf .NET Core 3.1 und Mono über [SimpleJob(RuntimeMoniker.NetCoreApp31)] und [SimpleJob(RuntimeMoniker.Mono)] ausführen.
Wenn Sie Attribute nicht mögen, können Sie den größten Teil der APIs über den fließenden Stil aufrufen und Code wie folgt schreiben:
ManualConfig . CreateEmpty ( ) // A configuration for our benchmarks
. AddJob ( Job . Default // Adding first job
. WithRuntime ( ClrRuntime . Net472 ) // .NET Framework 4.7.2
. WithPlatform ( Platform . X64 ) // Run as x64 application
. WithJit ( Jit . LegacyJit ) // Use LegacyJIT instead of the default RyuJIT
. WithGcServer ( true ) // Use Server GC
) . AddJob ( Job . Default // Adding second job
. AsBaseline ( ) // It will be marked as baseline
. WithEnvironmentVariable ( "Key" , "Value" ) // Setting an environment variable
. WithWarmupCount ( 0 ) // Disable warm-up stage
) ;Wenn Sie die Befehlszeilenerfahrung bevorzugen, können Sie Ihre Benchmarks über die Konsolenargumente in einer Konsolenanwendung konfigurieren (andere Arten von Anwendungen werden nicht unterstützt).
Zuverlässige Benchmarks enthalten immer eine Menge Boilerplate -Code.
Denken wir darüber nach, was Sie in einem typischen Fall tun sollten. Zunächst sollten Sie ein Pilotenexperiment durchführen und die beste Anzahl von Methodenaufrufe ermitteln. Als nächstes sollten Sie mehrere Aufwärm-Iterationen durchführen und sicherstellen, dass Ihr Benchmark einen stationären Zustand erreicht hat. Danach sollten Sie die wichtigsten Iterationen ausführen und einige grundlegende Statistiken berechnen. Wenn Sie einige Werte in Ihrem Benchmark berechnen, sollten Sie sie irgendwie verwenden, um die Eliminierung der toten Code zu verhindern. Wenn Sie Schleifen verwenden, sollten Sie sich um die Auswirkung der Schlaufe -Abläufe auf Ihre Ergebnisse kümmern (die von der Prozessorarchitektur abhängen können). Sobald Sie Ergebnisse erzielt haben, sollten Sie einige spezielle Eigenschaften der erhaltenen Leistungsverteilung wie Multimodalität oder extrem hohen Ausreißer überprüfen. Sie sollten auch den Aufwand Ihrer Infrastruktur bewerten und von Ihren Ergebnissen abziehen. Wenn Sie mehrere Umgebungen testen möchten, sollten Sie die Messungen in jedem von ihnen durchführen und die Ergebnisse manuell aggregieren.
Wenn Sie diesen Code von Grund auf neu schreiben, ist es einfach, einen Fehler zu machen und Ihre Maße zu verderben. Beachten Sie, dass es sich um eine verkürzte Version der vollständigen Checkliste handelt, die Sie beim Benchmarking folgen sollten: Es gibt viele zusätzliche versteckte Fallstricke, die angemessen behandelt werden sollten. Glücklicherweise sollten Sie sich darüber keine Sorgen machen, denn Benchmarkdotnet wird dieses langweilige und zeitaufwändige Sachen für Sie ausführen.
Darüber hinaus kann die Bibliothek Ihnen bei einigen erweiterten Aufgaben helfen, die Sie während der Untersuchung möglicherweise ausführen möchten. Zum Beispiel kann BenchmarkDotNet den verwalteten und nativen Speicherverkehr und den Drucklisten für Ihre Benchmarks messen.
Viele handgeschriebene Benchmarks erzeugen falsche Zahlen, die zu falschen Geschäftsentscheidungen führen. Benchmarkdotnet schützt Sie vor den meisten Fallstricks mit Benchmarking und ermöglicht eine hohe Messungspräzision.
Sie sollten sich keine Sorgen über die perfekte Anzahl von Methodenaufrufs, die Anzahl der Aufwärmen und die tatsächlichen Iterationen machen: Benchmarkdotnet versucht, die besten Benchmarking-Parameter auszuwählen und einen guten Kompromiss zwischen der Messprävision und der Gesamtdauer aller Benchmark-Läufe zu erzielen. Sie sollten also keine magischen Zahlen verwenden (wie "Wir sollten hier 100 Iterationen ausführen"), die Bibliothek wird es für Sie basierend auf den Werten statistischer Metriken tun.
Benchmarkdotnet verhindert auch das Benchmarking nicht optimierter Baugruppen, die mit dem Debug-Modus erstellt wurden, da die entsprechenden Ergebnisse unzuverlässig sind. Die Bibliothek druckt eine Warnung aus, wenn Sie einen angehängten Debugger haben, wenn Sie einen Hypervisor (Hyperv, VMware, VirtualBox) verwenden oder wenn Sie andere Probleme mit der aktuellen Umgebung haben.
Während 6+ Jahren der Entwicklung haben wir Dutzende verschiedener Probleme konfrontiert, die Ihre Messungen beeinträchtigen können. Inside Benchmarkdotnet gibt es viele Heuristiken, Überprüfungen, Hacks und Tricks, die Ihnen helfen, die Zuverlässigkeit der Ergebnisse zu erhöhen.
Die Analyse von Leistungsdaten ist eine zeitaufwändige Aktivität, die Aufmerksamkeit, Kenntnis und Erfahrung erfordert. Benchmarkdotnet führt den Hauptteil dieser Analyse für Sie aus und präsentiert Ergebnisse in einer benutzerfreundlichen Form.
Nach den Experimenten erhalten Sie eine Zusammenfassungstabelle, die viele nützliche Daten über die ausgeführten Benchmarks enthält. Standardmäßig enthält es nur die wichtigsten Spalten, können jedoch leicht angepasst werden. Der Spaltensatz ist adaptiv und hängt von der Benchmark -Definition und den gemessenen Werten ab. Wenn Sie beispielsweise eine der Benchmarks als Basis markieren, erhalten Sie zusätzliche Spalten, mit denen Sie alle Benchmarks mit der Basislinie vergleichen können. Standardmäßig zeigt es immer die mittlere Spalte an, aber wenn wir einen großen Unterschied zwischen dem Mittelwert und den Medianwerten festgestellt haben, werden beide Spalten dargestellt.
Benchmarkdotnet versucht einige ungewöhnliche Eigenschaften Ihrer Leistungsverteilungen und druckt nette Nachrichten darüber. Zum Beispiel warnen Sie bei multimodaler Verteilung oder hohen Ausreißer. In diesem Fall können Sie die Ergebnisse scrollen und Histogramme im ASCII-Stil für jede Verteilung überprüfen oder schöne PNG-Diagramme mit [RPlotExporter] erzeugen.
Benchmarkdotnet überlastet Sie nicht mit Daten. Abhängig von Ihren Ergebnissen werden nur die wesentlichen Informationen angezeigt: Sie können die Zusammenfassung für primitive Fälle gering halten und sie nur für komplizierte Fälle erweitern. Natürlich können Sie zusätzliche Statistiken und Visualisierungen manuell anfordern. Wenn Sie die summarische Ansicht nicht anpassen, ist die Standardpräsentation so viel benutzerfreundlich wie möglich. :)
Benchmarkdotnet ist keine Silberkugel, die alle Ihre Benchmarks auf magische Weise korrekt macht und die Messungen für Sie analysiert. Selbst wenn Sie diese Bibliothek verwenden, sollten Sie immer noch wissen, wie Sie Benchmark -Experimente entwerfen und wie Sie basierend auf den Rohdaten korrekte Schlussfolgerungen ziehen. Wenn Sie mehr über Benchmarking -Methodik und gute Praktiken erfahren möchten, wird empfohlen, ein Buch von Andrey Akinshin (The BenchmarkdotNet -Projektleiter) zu lesen: "Pro .net Benchmarking". Verwenden Sie diese eingehende Anleitung, um Benchmarks korrekt zu entwerfen, die wichtigsten Leistungsmetriken von .NET-Anwendungen zu messen und die Ergebnisse zu analysieren. In diesem Buch werden Dutzende von Fallstudien vorgestellt, mit denen Sie komplizierte Benchmarking -Themen verstehen können. Sie werden gemeinsame Fallstricke vermeiden, die Genauigkeit Ihrer Messungen steuern und die Leistung Ihrer Software verbessern.
Benchmarkdotnet ist bereits eine stabile Bibliothek mit Vollfaszination, die die Durchführung von Leistungsuntersuchungen auf professioneller Ebene ermöglicht. Und es entwickelt sich weiter! Wir fügen ständig neue Funktionen hinzu, aber wir haben zu viele neue coole Ideen. Jede Hilfe wird geschätzt. Sie können neue Funktionen entwickeln, Fehler beheben, die Dokumentation verbessern oder andere coole Dinge durchführen.
Wenn Sie einen Beitrag leisten möchten, lesen Sie den beitragenden Leitfaden und die Up-für-Grabs-Probleme. Wenn Sie neue Ideen haben oder sich über Fehler beschweren möchten, können Sie ein neues Problem erstellen. Lassen Sie uns das beste Werkzeug zum gemeinsamen Benchmarking erstellen!
Dieses Projekt hat den vom Mitwirkenden Covenant definierten Verhaltenskodex übernommen, um das erwartete Verhalten in unserer Community zu klären. Weitere Informationen finden Sie im Verhaltenskodex der .NET Foundation.
Benchmarkdotnet wird vom AWS Open Source Software Fund unterstützt.