Benchmarking und Zeitmessung von Befehlen und oder Funktionen

Benchmarking und Zeitmessung von Befehlen und oder Funktionen

Wer Code profilen möchte und keinen Profiler zur Hand hat, oder ein Profiler z. B. nicht passend ist, kennt vermutlich die typische Vorgehensweise: Zeitmesser instanziieren, starten, Befehl ausführen, Zeitmesser stoppen, Zeit auslesen und ausgeben.

Und das dann für jeden Befehl noch einmal.

Mithilfe von Lambdas läßt sich das alles deutlich schöner machen.

Durch die Benutzung von Lambda Expression lassen sich anonyme Methoden erzeugen, die dann von einer Benchmarking Funktion ausgeführt werden kann, die sich jeweils um die Zeiterfassung kümmert.

Die Funktion ist recht einfach:

1
2
3
4
5
6
7
8
public static long Benchmark(Action action)
{
    System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
    watch.Start();
    action();
    watch.Stop();
    return watch.ElapsedMilliseconds;
}

und kann dann z. B. so aufgerufen werden:

1
int elapsed = Benchmark(() => WriteLine("Spieglein, Spieglein an der Wand, wie lange dauert meine Ausführung?"));

Die leere Klammer () auf der linken Seite besagt hier, daß wir keine Eingabeparameter für die Lambda-Expression haben (und die dürfen wir auch nicht haben, die Benchmark-Funktion definiert Action ja auch ohne Parameter).

Parameter brauchen wir in diesem Fall jedoch auch nicht, da wir ja ohne Probleme Variablen verwenden können.

Sollte man das ganze noch etwas einfacher bzw. spezieller haben wollen, kann man dies so machen:

1
2
3
4
5
6
7
8
9
public static void BenchmarkWithTraceOrExecute(string msg, Action action)
{
#if DEBUG
    long ms = Benchmark(action);
    System.Diagnostics.Debug.WriteLine(msg + ": " + ms + "ms passed.");
#else
    action();
#endif
}

Mit dieser Funktion wird im Release Build die Aktion ausgeführt, im Debug Build wird die Laufzeit, mit einer kurzen Nachricht zur Beschreibung versehen, im Debug-Output ausgegeben. Der Aufruf erfolgt dann ähnlich wie zuvor:

1
2
3
4
5
6
BenchmarkWithTraceOrExecute("Einfaches Beispiel", () =>
{
    WriteLine("Spieglein, Spieglein an der Wand, wie lange dauert meine Ausführung?"));
    int i = 3 + 7;
    WriteLine("3 + 7 = " + i);
}

Fazit: gut für einfache Ausführungsdauer-Messungen

Eine nette und einfache Möglichkeit, Geschwindigkeitsmessungen vom Erstellungsaufwand zu beschleunigen – insbesondere muß hier (wenn man nicht möchte) der Code nach der Optimierung (dafür wird ja normalerweise die Messung gemacht) nicht wieder entfernt werden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.