Liersch.Profiling – .NET-Bibliothek zur Performanceanalyse

NuGet GitHub last commit

Die .NET-Bibliothek Liersch.Profiling umfasst Funktionen zur Messung der Ausführungszeit von Funktionen. Es werden alle wichtigen .NET-Plattformen unterstützt (ab .NET Framework 4.5, ab .NET Core 2.0 und ab .NET Standard 2.0). Alle wesentlichen Änderungen sind in der Datei CHANGELOG.md protokolliert.

Zeitmessung

Die Funktion MeasurePerformance der Klasse MeasuringTools ermittelt die Performance der angegebenen Funktionen. Für jede Funktion wird ein MeasuringData-Objekt geliefert. Darin sind die Anzahl der Aufrufe und die dafür benötigte Zeit gespeichert. Die Zeitmessung erfolgt auf Basis der Klasse Stopwatch. Die Genauigkeit ist abhängig von der eingesetzten Hardware. Bei dieser Art der Messung wird das Ergebnis stets von den zur selben Zeit laufenden Prozessen und deren Threads beeinflusst.

Action a1=() => Thread.Sleep(10);
Action a2=() => Thread.Sleep(20);
MeasuringData[] md=MeasuringTools.MeasurePerformance(a1, a2);
Console.WriteLine("Thread.Sleep(10) => "+md[0].Format());
Console.WriteLine("Thread.Sleep(20) => "+md[1].Format());

Messung der CPU-Zeit

Alternativ kann die Funktion MeasureProcessorTime genutzt werden, um die während der Messung vom Prozess benötigte Prozessorzeit zu ermitteln. Die Beeinflussung durch andere, zur Zeit der Messung laufende Prozesse sollte wesentlich geringer sein, als beim Stopwatch-basierten Ansatz.

MeasureProcessorTime kann nicht die Zeit messen, die für das Warten auf bestimmte Ereignisse benötigt wird (z. B. EventWaitHandle.Wait oder Thread.Sleep), da für diese Art des Wartens keine CPU-Zeit benötigt wird.

Automatisierte Messungen

Wenn mehrere Testfunktionen vorhanden sind, können diese automatisiert aufgerufen werden. Testfunktionen müssen mit dem Attribut MeasuringAttribute markiert sein und MeasuringData-Objekte zurückgeben.

static class Tests
{
  [Measuring(1, "SleepTicks(1) vs. SleepTicks(2)")]
  public static MeasuringData[] TestSleepTicks()
  {
    Action a1=() => Functions.SleepTicks(1);
    Action a2=() => Functions.SleepTicks(2);
    return MeasuringTools.MeasurePerformance(a1, a2);
  }

  [Measuring(2, "SleepMilliseconds(1) vs. SleepMilliseconds(2)")]
  public static MeasuringData[] TestSleepMilliseconds()
  {
    Action a1=() => Functions.SleepMilliseconds(1);
    Action a2=() => Functions.SleepMilliseconds(2);
    return MeasuringTools.MeasurePerformance(a1, a2);
  }

  [Measuring(3, "Thread.Sleep(10) vs. Thread.Sleep(20)")]
  public static MeasuringData[] TestThreadSleep()
  {
    Action a1=() => Thread.Sleep(10);
    Action a2=() => Thread.Sleep(20);
    return MeasuringTools.MeasurePerformance(a1, a2);
  }
}

Der automatisierte Aufruf aller Testmethoden erfolgt mit Hilfe der Funktion RunTests der Klasse MeasuringTools. Die Beschreibungstexte und Messergebnisse werden auf der Konsole ausgegeben. Wenn eine Klasse nur statische Testfunktionen enthält oder über einen Standardkonstruktor verfügt, reicht es aus, den Typ anstelle einer Instanz zu übergeben.

MeasuringTools.RunTests(typeof(Tests));

Genauigkeit der Messung

Unabhängig von der Messmethode gibt es verschiedene Faktoren, die eine Messung beeinträchtigen. Funktionen, die viele Objekte erzeugen, werden beispielsweise von einer unter Umständen stattfindenden Garbage Collection beeinflusst. Deshalb wird vor jeder Messung eine Garbage Collection erzwungen, um eine einigermaßen vergleichbare Startsituation herzustellen. Andere Threads, die auf demselben Prozessorkern aktiv sind, können das Messergebnis ebenfalls verfälschen.

Wertformatierung

Die Klasse Formatter enthält Funktionen für die Formatierung von einheitenbehafteten Werten. Die Funktionen sind auch unabhängig von den eigentlichen Messfunktionen nutzbar. Die aktuelle Implementierung der Formatierungsfunktionen arbeitet generell kulturunabhängige (siehe CultureInfo.InvariantCulture).

Console.WriteLine("Duration: "+Formatter.FormatSeconds(md.Duration.TotalSeconds, 1));
Console.WriteLine("Score: "+Formatter.FormatDecimal(md.Score, 1, "Hz"));

Copyright

Copyright © 2020 Steffen Liersch
https://www.steffen-liersch.de/

Verweise

Der Quellcode wird auf GitHub gepflegt:
https://github.com/steffen-liersch/Liersch.Profiling

Pakete können über NuGet heruntergeladen werden:
https://www.nuget.org/packages/Liersch.Profiling

Ähnliche Artikel

Schreiben Sie einen Kommentar