C# Stopwatch

TimeSpan

Stopwatch measures time elapsed. It is useful for micro-benchmarks in code optimization. It can perform routine and continuous performance monitoring. The Stopwatch type, found in System.Diagnostics, is useful in many contexts.

Tip:Stopwatch provides easy-to-use and accurate measurement of time elapsed. It helps with benchmarking.

Benchmark

Example

First, Stopwatch is a class in the .NET Framework that is ideal for timing any operation in your C# programs. You must create Stopwatch as an instance. This makes it useful in multithreaded applications or websites.

Program that uses Stopwatch: C#

using System;
using System.Diagnostics;
using System.Threading;

class Program
{
    static void Main()
    {
	// Create new stopwatch
	Stopwatch stopwatch = new Stopwatch();

	// Begin timing
	stopwatch.Start();

	// Do something
	for (int i = 0; i < 1000; i++)
	{
	    Thread.Sleep(1);
	}

	// Stop timing
	stopwatch.Stop();

	// Write result
	Console.WriteLine("Time elapsed: {0}",
	    stopwatch.Elapsed);
    }
}

Output

Time elapsed: 00:00:01.0001477
Squares

The code includes the "using System.Diagnostics" namespace at the top. This is where the Stopwatch class is defined in the Framework. You can see the Stopwatch is created with the new operator in Main.

New

The Start method tells the Stopwatch object to store the current time internally. It queries the Windows performance code to find the current tick count of the system. This is extremely accurate.

Note:The calls to Thread.Sleep in the loop are not useful and are just for the example.

And:You can ignore them, except to note that they take about one second to complete.

SleepString type

We call Stop on the instance Stopwatch. This tells the Stopwatch to capture the current tick count of the system, also very accurate. The Console.WriteLine method is called to output the time of the Stopwatch instance.

Console.WriteLine

Tip:The Elapsed property on Stopwatch is a TimeSpan struct, which overrides the ToString method.

TimeSpanToString

StartNew

Method call

For your benchmarks or diagnostics code, you probably will prefer the StartNew method. This uses a creational design pattern to return a new instance from a static type method. It eliminates typing and simplifies your code.

This method is called to create a new instance of StopWatch. For the example, we show the var syntax, which is a shorthand for the type declaration. We access the System.Diagnostics namespace in the statement.

Var
Program that uses StartNew: C#

class Program
{
    static void Main()
    {
	// Create new stopwatch
	var stopwatch = System.Diagnostics.Stopwatch.StartNew();

	// Do something
	// [omitted]

	// Stop timing
	stopwatch.Stop();

	// Write the results [omitted]
    }
}

Properties

Framework: NET

The Stopwatch class has some static properties and fields on it, including Frequency and IsHighResolution. These determine the internal configuration of Stopwatch, which depends on the machine and the installation of the .NET Framework.

Frequency:This returns the number of ticks the Stopwatch uses per second. It is used to convert ElapsedTicks to a figure in seconds.

IsHighResolution:Tells whether the Stopwatch is using high resolution timing. Stopwatch isn't as useful when this is false.

IsRunning:This is only useful if your code uses Stop or Reset in unpredictable ways. For most micro-benchmarks, it is not necessary.

Framework: NET

Values. Next, we see possible values of several static properties and methods. These values were determined by printing the output of the expressions on the left. The Frequency indicates the number of ticks per second.

Stopwatch properties:

Stopwatch.Frequency:        14318180
Stopwatch.IsHighResolution: True
Stopwatch.GetTimestamp:     174412139895

ElapsedTicks

Property

This example uses the ElapsedTicks instance property on Stopwatch. This is internally a readonly signed System.Int64 value. When you capture ElapsedTicks, you have to manually do the calculations to convert the values to seconds.

Program that uses ElapsedTicks: C#

using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
	// Create a new Stopwatch
	var stopwatch = Stopwatch.StartNew();

	// Capture the elapsed ticks and write them to the console
	long ticks1 = stopwatch.ElapsedTicks;
	Console.WriteLine(ticks1);

	// Capture the ticks again. This will be a larger value
	long ticks2 = stopwatch.ElapsedTicks;
	Console.WriteLine(ticks2);
    }
}

Output

11
7092 <-- This means the Console.WriteLine took over 7000 ticks
Long type

The example code first creates a new Stopwatch with StartNew, and then captures the ElapsedTicks long property twice. The values are printed to the screen. The Console.WriteLine here was the most expensive operation. It took 7081 ticks.

Long

Note:The ElapsedTicks value from Stopwatch is not normally the same as the DateTime.Ticks value.

Note 2:Stopwatch ticks are far more accurate, when the IsHighResolution property is true. Otherwise, they are equivalent.

Restart

Arrow indicates looping

The Stopwatch provides Restart and Reset methods. Restart sets the timer information to zero. It then calls Start again on the Stopwatch, so you can time further statements. This is like calling Reset and Start.

Reset, meanwhile, only sets the timer information to zero. It does not call Start on the Stopwatch. So you will have to call Reset and then Start explicitly. In this program, try replacing Restart with Reset.

Program that uses Restart method: C#

using System;
using System.Diagnostics;
using System.Threading;

class Program
{
    static void Main()
    {
	Stopwatch stop = Stopwatch.StartNew();
	Thread.Sleep(1000);
	stop.Restart();
	Thread.Sleep(1000);
	Console.WriteLine(stop.ElapsedMilliseconds);
    }
}

Output

1000

Performance

Performance optimization

Let's address the performance impact caused by instantiating a Stopwatch. The Stopwatch class is slower than many operations. This applies when you are using Stopwatch throughout the lifetime of your application for routine monitoring.

Result:Using a Stopwatch is more expensive than simple operations in the .NET Framework.

And:For this reason, Stopwatch itself can become a performance problem. We should not use it in production code in tight loops.

Program that times Stopwatch: C#

using System;
using System.Diagnostics;

class Program
{
    const int _max = 1000000;
    static void Main()
    {
	var s1 = Stopwatch.StartNew();
	for (int i = 0; i < _max; i++)
	{
	    var sw = Stopwatch.StartNew();
	    sw = null;
	}
	s1.Stop();
	Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
	    _max).ToString("0.00 ns"));
	Console.Read();
    }
}

Result

600.64 ns

For context, simple additions and multiplications require only a couple nanoseconds on most systems. The cost of creating and starting a Stopwatch thus could make simple methods far slower.

Summary

The Stopwatch class has many use cases. Stopwatch is an incredibly useful class for performing diagnostics or benchmarks. It is simple and powerful. It can lead to higher quality software.


C#: Time