Zeitmessung mit C# und der Stopwatch-Klasse

In meinem Beitrag vom 6.Juni 2009 bin ich schon einmal auf die Zeitmessung in C# unter Verwendung von System.Environment.TickCount eingegangen.

Ab dem .NET Framework 2 steht eine Klasse Stopwatch im Namensraum System.Diagnostics zur Verfügung. Damit sind sehr genaue Messungen möglich. Insbesondere bei kürzeren Schleifen liefert TickCount meist 0 Millisekunden zurück. Das liegt daran, dass TickCount nur eine Genauigkeit von 1/20 Sekunde hat. Trotzdem ist TickCount bei Zeitmessungen sehr genau – lediglich bei extrem kurzen Messzeiten wird es ungenau oder kann gar nicht erst erfasst werden.

Die Stopwatch Klasse unterstützt so genannte High-Resolution-Timer und ermöglicht damit extrem genaue Zeitmessungen – vorausgesetzt die Hardware verfügt über einen High-Resolution-Timer. Feststellen kann man dies über das statische Property IsHighResolution der Stopwatch-Klasse. Allerdings sollte man bei Experimenten daran denken, dass es sich bei einem Betriebssystem wie Windows um ein Multitasking-System handelt. Je nachdem, welche Aktionen vom Betriebssystem im Hintergrund durchgeführt werden (man denke z.B.an Antivirussoftware), kann es bei den Messungen zu entsprechenden Schwankungen kommen. Diese Tatsache betrifft aber nicht nur die Stopwatch-Klasse, sondern auch System.Environment.TickCount.

Ich möchte hier jetzt nicht alle Methoden und Properties auflisten und erklären. Vielmehr beschränke ich dies auf die wichtigsten und auch im Beispielcode verwendeten Elemente.
Wichtige Methoden sind z.B. Start(), Stop() oder Reset(). Das Property ElapsedMilliseconds liefert die Anzahl der verstrichenen Millisekunden – ist die Messung kürzer als 1 Millisekunde gewesen, erhält man dann (wie bei TickCount) den Wert 0. In dem Fall arbeitet man besser mit den Ticks. Das Property ElapsedTicks liefert die Anzahl der vergangenen Ticks. Das statische Property Stopwatch.Frequency liefert die Anzahl der Ticks pro Sekunde.

Der nachfolgende Code demonstriert die Verwendung der Stopwatch-Klasse in einer Konsolenanwendung. Als erstes wird eine Messung mit System.Environment.TickCount durchgeführt. Danach erfolgt eine Messung mit der Stopwatch-Klasse.

using System;

using System.Diagnostics;

namespace StopWatchTest

{

class Program

{

  static void Main()

  {

   // Zeitmessung mit C# und dem .NET Framework

   // unter Verwendung der Klasse StopWatch

   // im Namensraum System.Diagnostics

   Console.WriteLine(„Zeitmessung mit C# und der StopWatch-Klasse“);

   Console.WriteLine();

   Console.WriteLine(„1. Messung mit System.Environment.TickCount“);

   int firstTime = Environment.TickCount;

   DoBigLoop();

   int lastTime = Environment.TickCount;

   Console.WriteLine(„Ergebnis BigLoop: {0} Millisekunden“, lastTime – firstTime);

   firstTime = Environment.TickCount;

   DoSmallLoop();

   lastTime = Environment.TickCount;

   Console.WriteLine(„Ergebnis SmallLoop: {0} Millisekunden“, lastTime – firstTime);

   // Verwendung der StopWatch Klasse im Namensraum System.Diagnostics

   Console.WriteLine();

   Console.WriteLine(„2. Messung mit der StopWatch Klasse“);

   Stopwatch watch = new Stopwatch();

   Console.WriteLine(„Ticks pro Sekunde: {0}“, Stopwatch.Frequency);

   Console.WriteLine(„HighResolutionTimer: {0}“, Stopwatch.IsHighResolution);

   watch.Start();

   DoBigLoop();

   watch.Stop();

   Console.WriteLine(„Ergebnis BigLoop:\n{0} Ticks -> entspricht {1} Millisekunden“,

   watch.ElapsedTicks, watch.ElapsedMilliseconds);

   watch.Reset();

   watch.Start();

   DoSmallLoop();

   // watch.ElapsedMilliseconds würde hier 0 liefern!

   Console.WriteLine(„Ergebnis SmallLoop:\n{0} Ticks -> entspricht {1} Millisekunden“,

              watch.ElapsedTicks, (1.0/Stopwatch.Frequency) * watch.ElapsedTicks * 1000);

   Console.ReadKey();

}

  static void DoBigLoop()

  {

   long val = 0;

   for (int i = 0; i < 100000000; i++)

     val += 50;

  }

  static void DoSmallLoop()

  {

   long val = 0;

   for (int i = 0; i < 50; i++)

     val += i * 50;

  }

}

}

Weitere Informationen zur StopWatch-Klasse sind unter dem nachfolgenden Link zu finden

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

image