As software engineers, we know system precision and performance are essential, and the ability to measure time can come in handy to achieve this goal. That’s where functionalities to capture and analyze time intervals can come in handy. We can leverage this to achieve goals such as optimizing code execution, benchmarking algorithms, or tracking application performance.
In this article, we are going to learn how that works in C#.
Without further delay, let’s start!
Why Should We Use Stopwatch in C#?
In C#, we can use the Stopwatch
class to determine our code’s execution time. We can use these findings to improve our algorithms’ performance, which is useful during performance optimization processes. For example, let’s use Start()
and Stop()
method calls to calculate elapsed time:
public static Stopwatch CreateRandomArray(int size) { var stopWatch = new Stopwatch(); stopWatch.Start(); var array = new int[size]; for (int i = 0; i < size; i++) array[i] = Random.Shared.Next(); stopWatch.Stop(); return stopWatch; }
Our example calculates how long it takes to create a random integer array of a given size.
On top of that, we can use the Stopwatch
class to compare the runtime for different algorithms. These performance benchmarks can help us determine algorithm complexity.
Using Stopwatch in C#
Now that we know why using Stopwatch
can be useful; let’s see how we can leverage it in C#.
Using our example, let’s verify that our Stopwatch
instance properties are of the correct types:
var arraySize = 10; var stopWatch = StopWatchMethods.CreateRandomArray(arraySize); Assert.IsInstanceOfType(stopWatch, typeof(Stopwatch)); Assert.IsInstanceOfType(stopWatch.Elapsed, typeof(TimeSpan)); Assert.IsInstanceOfType(stopWatch.ElapsedMilliseconds, typeof(long)); Assert.IsInstanceOfType(stopWatch.ElapsedTicks, typeof(long));
To start with, we can use the Elapsed
, ElapsedMilliseconds
, and ElapsedTicks
properties to determine our example’s execution time.
In some cases, we may want to check whether our Stopwatch
instance is still running, and that’s where we can take advantage of the IsRunning
property:
Assert.IsFalse(stopWatch.IsRunning);
In our case, we know that our instance is not running so it returns false
.
Apart from properties, we can invoke some methods to manipulate how our Stopwatch
instance works. For example, Reset()
and Restart()
methods have different use cases. The latter terminates the current interval measurement and sets the elapsed time to zero, while the former starts measuring the elapsed time after it has been set to zero:
stopWatch.Reset(); Assert.AreEqual(stopWatch.Elapsed, TimeSpan.Zero); stopWatch.Restart();
After invoking the Restart()
method, we can now test that our Stopwatch
instance is running:
Assert.AreEqual(stopWatch.Elapsed.CompareTo(TimeSpan.Zero), 1); Assert.IsTrue(stopWatch.IsRunning);
Lastly, after invoking the Stop()
method, we can verify that our Stopwatch instance is not running:
stopWatch.Stop(); Assert.IsFalse(stopWatch.IsRunning);
Now that we have verified our properties, fields, and methods, let’s invoke our CreateRandomArray()
method in our Program.cs
file:
var stopWatch = StopWatchMethods.CreateRandomArray(1000); Console.WriteLine($@"Elapsed Time: {stopWatch.Elapsed} Elapsed Milliseconds: {stopWatch.ElapsedMilliseconds} Elapsed Ticks: {stopWatch.ElapsedTicks} Is Running: {stopWatch.IsRunning} Frequency: {Stopwatch.Frequency} Using High Resolution: {Stopwatch.IsHighResolution}");
The Stopwatch
class has two static read-only fields: Frequency
and IsHighResolution
. The former returns the timer frequency denoted as ticks per second, while the latter indicates whether the timer uses a high-resolution performance timer. Therefore, we retrieve their values directly as Stopwatch.Frequency
and Stopwatch.IsHighResolution
instead of using our stopWatch
class instance.
Let’s check the result after executing the program:
Elapsed Time: 00:00:00.0002089 Elapsed Milliseconds: 0 Elapsed Ticks: 2089 Is Running: False Frequency: 10000000 Using High Resolution: True Press any key to close this window . . .
In some cases, we may want to initialize a new Stopwatch
instance and restart the process of measuring elapsed time. That’s where we can invoke the StartNew()
method:
var stopWatch = Stopwatch.StartNew();
This approach is different from simply initializing a new Stopwatch
instance with the default constructor. When we use the StartNew()
method, apart from initializing a new instance, we automatically start measuring elapsed time.
Conclusion
In summary, we learn how to use the Stopwatch
class in C# in this article. We can leverage the Stopwatch
class to reveal inefficiencies in database queries, network operations, and other critical processes, which can be useful when optimizing them.