Benchmarking von C # -Code mit BenchmarkDotNet

BenchmarkDotNet ist eine leichte, leistungsstarke Open-Source-.NET-Bibliothek, mit der Sie Ihre Methoden in Benchmarks umwandeln, diese Methoden verfolgen und anschließend Einblicke in die erfassten Leistungsdaten erhalten können. Es ist einfach, BenchmarkDotNet-Benchmarks zu schreiben, und die Ergebnisse des Benchmarking-Prozesses sind ebenfalls benutzerfreundlich.

Sie können BenchmarkDotNet nutzen, um sowohl .NET Framework- als auch .NET Core-Anwendungen zu bewerten. In diesem Artikel werden wir untersuchen, wie wir mit BenchmarkDotNet in .NET Core arbeiten können. Sie finden BenchmarkDotNet auf GitHub.

Um mit den in diesem Artikel bereitgestellten Codebeispielen arbeiten zu können, muss Visual Studio 2019 auf Ihrem System installiert sein. Wenn Sie noch keine Kopie haben, können Sie Visual Studio 2019 hier herunterladen. 

Erstellen Sie ein Konsolenanwendungsprojekt in Visual Studio

Zunächst erstellen wir ein .NET Core-Konsolenanwendungsprojekt in Visual Studio. Angenommen, Visual Studio 2019 ist auf Ihrem System installiert, führen Sie die folgenden Schritte aus, um ein neues .NET Core-Konsolenanwendungsprojekt in Visual Studio zu erstellen.

  1. Starten Sie die Visual Studio-IDE.
  2. Klicken Sie auf "Neues Projekt erstellen".
  3. Wählen Sie im Fenster "Neues Projekt erstellen" aus der Liste der angezeigten Vorlagen "Konsolen-App (.NET Core)" aus.
  4. Weiter klicken.
  5. Geben Sie im nächsten Fenster "Konfigurieren Sie Ihr neues Projekt" den Namen und den Speicherort für das neue Projekt an.
  6. Klicken Sie auf Erstellen.

Dadurch wird ein neues .NET Core-Konsolenanwendungsprojekt in Visual Studio 2019 erstellt.

Beachten Sie, dass beim Erstellen des Konsolenanwendungsprojekts die resultierende Programmklasse (die automatisch in der Datei Program.cs generiert wird) folgendermaßen aussieht:

Klassenprogramm

{

   statische Leere Main (string [] args)

  {

      Console.WriteLine ("Hallo Welt!");

  }}

}}

Wir werden dieses Projekt und diese Programmklasse verwenden, um in den folgenden Abschnitten dieses Artikels mit BenchmarkDotNet zu arbeiten.

Installieren Sie das BenchmarkDotNet NuGet-Paket

Um mit BenchmarkDotNet arbeiten zu können, müssen Sie das BenchmarkDotNet-Paket installieren. Sie können dies entweder über den NuGet Package Manager in der Visual Studio 2019-IDE oder durch Ausführen des folgenden Befehls in der NuGet Package Manager-Konsole tun:

Install-Package BenchmarkDotNet

Warum Benchmark-Code?

Ein Benchmark ist eine Messung oder eine Reihe von Messungen, die sich auf die Leistung eines Codeteils in einer Anwendung beziehen. Das Benchmarking von Code ist wichtig, um die Leistungsmetriken der Methoden in Ihrer Anwendung zu verstehen. Es ist immer ein guter Ansatz, die Metriken zur Hand zu haben, wenn Sie Code optimieren. Für uns ist es sehr wichtig zu wissen, ob die im Code vorgenommenen Änderungen die Leistung verbessert oder verschlechtert haben. Durch Benchmarking können Sie auch die Teile des Codes in der Anwendung eingrenzen, die überarbeitet werden müssen.

Schritte zum Benchmarking von Code mit BenchmarkDotNet

Um BenchmarkDotNet in Ihrer .NET Framework- oder .NET Core-Anwendung auszuführen, müssen Sie die folgenden Schritte ausführen:

  1. Fügen Sie das erforderliche NuGet-Paket hinzu
  2. Fügen Sie Ihren Methoden Benchmark-Attribute hinzu
  3. Erstellen Sie eine BenchmarkRunner-Instanz
  4. Führen Sie die Anwendung im Freigabemodus aus

Erstellen Sie eine Benchmarking-Klasse in .NET Core

Öffnen Sie die Datei Program.cs und schreiben Sie dort den folgenden Code ein.

  [MemoryDiagnoser]

   öffentliche Klasse MemoryBenchmarkerDemo

    {

        int NumberOfItems = 100000;

        [Benchmark]

        öffentlicher String ConcatStringsUsingStringBuilder ()

        {

            var sb = new StringBuilder ();

            für (int i = 0; i <NumberOfItems; i ++)

            {

                sb.Append ("Hallo Welt!" + i);

            }}

            return sb.ToString ();

        }}

        [Benchmark]

        öffentlicher String ConcatStringsUsingGenericList ()

        {

            var list = neue Liste (NumberOfItems);

            für (int i = 0; i <NumberOfItems; i ++)

            {

                list.Add ("Hallo Welt!" + i);

            }}

            return list.ToString ();

        }}

    }}

Das obige Programm zeigt, wie Sie Methoden für das Benchmarking schreiben können. Beachten Sie die Verwendung des Benchmark-Attributs über jeder der zu vergleichenden Methoden.

In der Main-Methode der Program.cs-Datei müssen Sie den anfänglichen Startpunkt angeben - die BenchmarkRunner-Klasse. Auf diese Weise können Sie BenchmarkDotNet informieren, Benchmarks für die angegebene Klasse auszuführen. Ersetzen Sie daher den Standardcode der Main-Methode in der Datei Program.cs mithilfe des folgenden Codeausschnitts.

statische Leere Main (string [] args)

{

   var summary = BenchmarkRunner.Run ();

}}

Führen Sie den Benchmark in Ihrer .NET Core-Anwendung aus

Wenn Sie die Anwendung im Debug-Modus ausführen, wird folgende Fehlermeldung angezeigt:

Beim Benchmarking sollten Sie immer sicherstellen, dass Sie Ihr Projekt im Release-Modus ausführen. Der Grund dafür ist, dass der Code während der Kompilierung sowohl für den Debug- als auch für den Release-Modus unterschiedlich optimiert wird. Der C # -Compiler führt im Release-Modus einige Optimierungen durch, die im Debug-Modus nicht verfügbar sind.

Daher sollten Sie Ihr Projekt nur im Release-Modus ausführen. Geben Sie zum Ausführen des Benchmarking den folgenden Befehl an der Visual Studio-Eingabeaufforderung an.

dotnet run -p BenchmarkDotNetDemo.csproj -c Release

Um optimale Ergebnisse zu erzielen, sollten Sie sicherstellen, dass alle Anwendungen geschlossen und alle unnötigen Prozesse gestoppt sind, bevor Sie Benchmarks ausführen.

Beachten Sie, dass die Laufzeit versucht, ein Benchmarking für nicht optimierten Code im Debug-Modus durchzuführen, wenn Sie den Konfigurationsparameter nicht angeben. Und es wird derselbe Fehler angezeigt, der in Abbildung 1 dargestellt ist.

Analysieren Sie die Benchmarking-Ergebnisse

Sobald die Ausführung des Benchmarking-Prozesses abgeschlossen ist, wird im Konsolenfenster eine Zusammenfassung der Ergebnisse angezeigt. Der Zusammenfassungsabschnitt enthält Informationen zur Umgebung, in der die Benchmarks ausgeführt wurden, z. B. die BenchmarkDotNet-Version, das Betriebssystem, die Computerhardware, die .NET-Version, Compilerinformationen und Informationen zur Leistung der Anwendung.

Einige Dateien werden auch im Ordner BenchmarkDotNet.Artifacts unter dem Stammordner der Anwendung erstellt. Hier ist eine Zusammenfassung der Ergebnisse. 

Wie aus der in Abbildung 2 gezeigten Zusammenfassung hervorgeht, wird für jede Benchmark-Methode eine Datenzeile angezeigt, in der die Leistungsmetriken wie die mittlere Ausführungszeit, die Sammlungen Gen 0, Gen 1, Gen 2 usw. angegeben sind.

Wenn Sie sich die in Abbildung 3 gezeigten Ergebnisse ansehen, können Sie feststellen, dass die ConcatStringUsingGenericList viel schneller ist als die ConcatStringUsingStringBuilder-Methode. Sie können auch sehen, dass nach dem Ausführen der ConcatStringUsingStringBuilder-Methode viel mehr Zuordnungen vorhanden sind.

Fügen Sie nun das RankColumn-Attribut über der MemoryBenchmarkerDemo-Klasse hinzu. Dadurch wird der Ausgabe eine zusätzliche Spalte hinzugefügt, die angibt, welche Methode schneller war. Führen Sie den Benchmarking-Prozess erneut mit dem folgenden Befehl aus.

dotnet run -p BenchmarkDotNetDemo.csproj -c Release

Wenn Sie diesen Befehl ausführen, wird der Benchmarking-Prozess gestartet und die Ausgabe angezeigt, nachdem der Benchmarking-Prozess erfolgreich ausgeführt wurde. Abbildung 4 unten zeigt die Ausgabe mit hinzugefügter RankColumn. 

BenchmarkDotNet ist ein nützliches Tool, mit dem Sie auf einfache Weise eine fundierte Entscheidung über die Leistungsmetriken Ihrer Anwendung treffen können. In BenchmarkDotNet wird der Aufruf einer Methode mit dem Benchmark-Attributsatz als Operation bezeichnet. Eine Iteration ist der Name einer Sammlung mehrerer Operationen. 

Sie können eine Demo-ASP.NET Core-Anwendung erkunden, die verschiedene Möglichkeiten zum Benchmarking des Codes veranschaulicht. Sie können die Anwendung aus dem ASP.NET-Repo auf GitHub herunterladen. 

So machen Sie mehr in C #: 

  • So testen Sie statische Methoden in C #
  • Wie man Gottobjekte in C # umgestaltet
  • Verwendung von ValueTask in C #
  • Verwendung der Unveränderlichkeit in C.
  • Verwendung von const, readonly und static in C #
  • Verwendung von Datenanmerkungen in C #
  • So arbeiten Sie mit GUIDs in C # 8
  • Wann wird eine abstrakte Klasse im Vergleich zur Schnittstelle in C # verwendet?
  • So arbeiten Sie mit AutoMapper in C #
  • Verwendung von Lambda-Ausdrücken in C #
  • So arbeiten Sie mit Action-, Func- und Predicate-Delegaten in C #
  • So arbeiten Sie mit Delegierten in C #
  • So implementieren Sie einen einfachen Logger in C #
  • So arbeiten Sie mit Attributen in C #
  • So arbeiten Sie mit log4net in C #
  • So implementieren Sie das Repository-Entwurfsmuster in C #
  • Wie man mit Reflexion in C # arbeitet
  • So arbeiten Sie mit dem Dateisystemwatcher in C #
  • So führen Sie eine verzögerte Initialisierung in C # durch
  • So arbeiten Sie mit MSMQ in C #
  • So arbeiten Sie mit Erweiterungsmethoden in C #
  • Wie wir Lambda-Ausdrücke in C #
  • Wann wird das flüchtige Schlüsselwort in C # verwendet?
  • Verwendung des Schlüsselwortsield in C #
  • So implementieren Sie Polymorphismus in C #
  • So erstellen Sie Ihren eigenen Taskplaner in C #
  • So arbeiten Sie mit RabbitMQ in C #
  • So arbeiten Sie mit einem Tupel in C #
  • Erkundung virtueller und abstrakter Methoden in C #
  • Verwendung des Dapper ORM in C #
  • Verwendung des Entwurfsmusters im Fliegengewicht in C #