So schreiben Sie Leistungstests mit NBench

Wenn Sie mit Anwendungen arbeiten, möchten Sie häufig die Speicherzuordnung, den Garbage Collection-Aufwand (GC) und den Durchsatz des Codes kennen. Ihre Anwendung ist möglicherweise langsam oder verbraucht möglicherweise viele Ressourcen, und Sie möchten herausfinden, was nicht stimmt.

Obwohl Sie Funktionsprobleme und Codefehler mithilfe von Komponententests und Codeüberprüfungen erkennen können, benötigen Sie möglicherweise noch eine Möglichkeit, Leistungsprobleme zu isolieren. Hier bietet sich NBench an. Dieser Artikel enthält eine Diskussion über NBench und wie wir damit Leistungstests für .NET-Anwendungen schreiben können.

Was ist NBench? Warum sollte ich es benutzen?

NBench ist ein beliebtes Framework für Leistungstests, mit dem die Leistung von Methoden in unserer Anwendung analysiert werden kann. NBench kann den Durchsatz des Codes Ihrer Anwendung, die Speicherzuordnung und den GC-Overhead messen, der mit der Rückgewinnung von Speicher verbunden ist, indem unerwünschte Objekte bereinigt werden.

Sie können NBench nutzen, um die Leistung Ihrer Anwendung ähnlich wie beim Schreiben von Komponententests mit den XUnit- oder NUnit-Frameworks zu testen. Das, was mir an NBench am besten gefällt, ist, dass es in Ihre Build-Pipeline integriert werden kann. Und obwohl NBench einen eigenen Läufer hat, können Sie NBench dennoch mit NUnit oder Resharper ausführen. Es fühlt sich an, als würden Sie Ihre Unit-Tests durchführen.

NBench wird als NuGet-Paket vertrieben. Angenommen, Visual Studio ist bereits auf Ihrem System installiert, können Sie NBench über den NuGet-Paketmanager oder mit dem folgenden Befehl in der Paketmanager-Konsole installieren.

Installationspaket NBench

Sie sollten auch das NBench.Runner-Paket installieren, mit dem Sie Ihren Benchmark ausführen. Sie können dies auch über NuGet tun oder den folgenden Befehl über die Paketmanagerkonsole ausführen.

Installationspaket NBench.Runner

Wenn Sie wie ich sind, möchten Sie Ihre NBench-Leistungstests mit NUnit ausführen. Möglicherweise möchten Sie auch Pro.NBench.xUnit verwenden. Mit Pro.NBench.xUnit können Sie NBench-Tests mit xUnit in ReSharper erkennen, ausführen oder debuggen. 

Schreiben von Leistungstests mit NBench

Lassen Sie uns untersuchen, wie wir Leistungstests mit NBench schreiben und ausführen können. Erstellen Sie ein neues Klassenbibliotheksprojekt und speichern Sie es unter einem hilfreichen Namen. Fügen Sie als Nächstes die oben genannten Pakete NBench und NBench.Runner hinzu. Hier ist der Beginn unserer NBench-Leistungstestmethode.

[PerfBenchmark (NumberOfIterations = 1, RunMode = RunMode.Throughput,

TestMode = TestMode.Test, SkipWarmups = true)]

[ElapsedTimeAssertion (MaxTimeMilliseconds = 5000)]

public void Benchmark_Performance_ElaspedTime ()

{

    // Schreiben Sie hier Ihren Code für das Benchmarking

}}

Beachten Sie, dass wir unsere Methode mithilfe des PerfBenchmarkAttributs markieren müssen, da wir die Leistung messen. Dieses Attribut teilt dem Läufer mit, was mit dieser Methode zu tun ist. Wir müssen auch ein oder mehrere Messattribute einschließen. Da wir die Ausführungsgeschwindigkeit testen, verwenden wir das ElapsedTimeAssertionAttribut, um die Zeit anzugeben, innerhalb der die Methode abgeschlossen sein soll. Es gibt viele andere Assertionsattribute, die Sie nutzen können. Die unterstützten Behauptungen in NBench umfassen Folgendes:

  • MemoryAssertionAttribute
  • GcTotalAssertionAttribute
  • ElapsedTimeAssertionAttribute
  • CounterTotalAssertionAttribute
  • GcThroughputAssertionAttribute
  • CounterThroughputAssertionAttribute
  • PerformanceCounterTotalAssertionAttribute
  • PerformanceCounterTotalAssertionAttribute

Die folgende Methode zeigt, wie wir die Leistung des Garbage Collectors bewerten können. Die Benchmark_Performance_GCMethode gibt uns die maximale, minimale, durchschnittliche und Standardabweichung der Sammlungen an, die für jede der drei GC-Generationen (Generation 0, 1 und 2) auftreten.

[PerfBenchmark (RunMode = RunMode.Iterations, TestMode = TestMode.Measurement)]

[GcMeasurement (GcMetric.TotalCollections, GcGeneration.AllGc)]

public void Benchmark_Performance_GC ()

{

    // Schreiben Sie hier Ihren Code für das Benchmarking

}}

Wenn Sie die Leistung anhand des Speicherverbrauchs bewerten möchten, finden Sie hier eine Testmethode, die Sie verwenden können.

[PerfBenchmark (Beschreibung,

NumberOfIterations = 5, RunMode = RunMode.Throughput, RunTimeMilliseconds = 2500, TestMode = TestMode.Test)]

[MemoryAssertion (MemoryMetric.TotalBytesAllocated, MustBe.LessThanOrEqualTo, ByteConstants.SixtyFourKb)]

public void Benchmark_Performance_Memory ()

{

    // Schreiben Sie hier Ihren Code für das Benchmarking

}}

Mit dem MemoryAssertionAttribut können Sie angeben, dass Sie die zu testende Methode so einschränken möchten, dass in jedem Durchlauf des Benchmarks nicht mehr als die angegebene Speichermenge belegt wird. Wenn die oben gezeigte Methode beispielsweise mehr als 64 KB Speicher belegt, gilt der Test als fehlgeschlagen.

Beachten Sie, dass ich in jedem der oben gezeigten Codebeispiele den Code übersprungen habe, der bewertet werden soll. Das Benchmarking der Methoden Ihrer Anwendung ist eine einfache Angelegenheit, Ihren Code in die von mir angegebenen Benchmark-Methoden einzufügen.

NBench ist ein plattformübergreifendes Open-Source-Framework für die automatisierte Leistungsprofilerstellung für .NET-Anwendungen und macht Leistungs- und Stresstests fast so einfach wie das Schreiben und Ausführen von Komponententests. Sie können NBench problemlos in Unit-Test-Frameworks wie NUnit integrieren. Sie können NBench sogar in xUnit integrieren und die Tests in ReSharper oder im Visual Studio Test Explorer ausführen. Sie können mehr über NBench auf GitHub und auf der Petabridge-Website erfahren.