BlackWasp
Performance
.NET 2.0

Speed Testing and the Stopwatch Class

Software must operate at a speed that is acceptable to the end user. Often large improvements can be made by improving the speed of short-lived but heavily used routines. The speed of these can be accurately measured using the .NET 2.0 Stopwatch class.

Speed Testing

Performance and scalability of software is a complex subject. Ensuring that an application meets the user's expectations requires that performance and scalability be considered throughout the development lifecycle. This is particularly important during the design phases, as poor design will almost certainly lead to poor user experience. However, a good design does not guarantee that a program will operate efficiently. The quality of the final code is equally important.

Measuring the speed of long-lived routines is fairly simple. Where a process takes several minutes to execute it can be timed using no more than a wristwatch. A ten percent improvement in execution time of a two-minute process saves twelve seconds and is therefore easily identified.

When measuring short-lived processes the timing requires much greater accuracy. This may include measurements of tiny fractions of a second for small processes that may be used many thousands of times. In earlier versions of the .NET framework this required use of Windows API functions. In the .NET framework 2.0, Microsoft introduced the Stopwatch class to simplify the process.

The Stopwatch Class

The Stopwatch class provides simple functionality for measuring time. As with a real stopwatch, objects of this class provide facilities to start, stop and reset a counter. However, with the Stopwatch class the timing is very accurate, allowing timing of operations that are completed in microseconds.

Example Code

To demonstrate the use of the Stopwatch class some sample code is required. In the following console application example, the program adds together all of the whole numbers between one and one million. This is the function that we will use the Stopwatch class to accurately time.

using System;

namespace StopWatchExample
{
    class Example
    {
        static void Main(string[] args)
        {
            long total = 0;

            for (int i=1;i<=1000000;i++)
                total += i;
        }
    }
}

Adding a Stopwatch Object

The Stopwatch class is found in the System.Diagnostics namespace. To make the code easier to read, this should be referenced with a using statement at the start of the sample program. A stopwatch object can then be added to the Main method as follows:

using System;
using System.Diagnostics;

namespace StopWatchExample
{
    class Example
    {
        static void Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();
            long total = 0;

            for (int i=1;i<=1000000;i++)
                total += i;
        }
    }
}

Controlling the Stopwatch

The Stopwatch class provides several method methods that allow a stopwatch object to be controlled. The Start method instructs the Stopwatch to being timing an operation. The Stop method instructs the Stopwatch to cease timing. If the Start method is used for a second time, the timing continues and the end result will be the total of both periods. To avoid this, the Stopwatch can be cleared back to zero using the Reset method. None of these three simple function calls require any parameters.

The required Stopwatch control methods can now be added to our sample code around the process that needs to be timed.

using System;
using System.Diagnostics;

namespace StopWatchExample
{
    class Example
    {
        static void Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();
            long total = 0;

            timer.Start();          // Start the timer

            for (int i=1;i<=1000000;i++)
                total += i;
                
            timer.Stop();           // Stop the timer
        }
    }
}

Reading the Stopwatch

The sample program now includes all of the additional code required to time the function. The only remaining task is to read the value of the Stopwatch object after stopping the timer. The Stopwatch class provides several properties that provide this information:

  • Elapsed. The Elapsed property returns a TimeSpan object representing the amount of time that the Stopwatch was active. TimeSpan objects are accurate to one tenth of a microsecond or one hundred nanoseconds.
  • ElapsedMilliseconds. The ElapsedMilliseconds property is less accurate than the Elapsed property as it only counts full milliseconds. For longer operations this accuracy can be quite adequate.
  • ElapsedTicks. This property returns the number of timer ticks counted by the Stopwatch. A timer tick is the smallest measurement of time possible for a Stopwatch object. The length of a timer tick can vary according to the specific computer and operating system used. The number of timer ticks per second can be identified by reading the static Frequency property of the Stopwatch class.

The selection of property to use for speed testing is dependant upon the task being measured. In our example, the Elapsed property provides the required level of accuracy and will be used to output the number of microseconds that the timer is active. This will be formatted with an accuracy of one decimal place. This is the highest accuracy possible for the TimeSpan class.

The sample can now be updated with the code required to output the execution time. The following shows the completed program:

using System;
using System.Diagnostics;

namespace StopWatchExample
{
    class Example
    {
        static void Main(string[] args)
        {
            Stopwatch timer = new Stopwatch();
            long total = 0;

            timer.Start();          // Start the timer

            for (int i=1;i<=1000000;i++)
                total += i;
                
            timer.Stop();           // Stop the timer
            
            decimal micro = (decimal)timer.Elapsed.Ticks / 10M;
            Console.WriteLine("Execution time was {0:F1} microseconds.", micro);
        }
    }
}

The sample may now be executed to see the time required to process the totalling operation. As the sample has been created as a console application, hit CTRL-F5 to execute the program. The output to the console will be similar to the following:

Execution time was 1493.7 microseconds.
Press any key to continue . . .
Link to this Page25 November 2006
RSS RSS Feed