Skip to content

Simple performance stopwatch

Jon P Smith edited this page Dec 14, 2024 · 16 revisions

I often needed to know how long a process took. I do use BenchmarkDotNet, but often I want a simpler method, and My solution is TimeThings. TimeThings is very easy to use and very flexible (see next section), but its nowhere as good at BenchmarkDotNet, but it only add ~2ms to the performance test. I use TimeThings to get a "quick and dirty" performance while I'm building a new application, but if performance is important I use BenchmarkDotNet to get accurate timing, for instance I used BenchmarkDotNet in my Net.DistributedFileStoreCache.

TimeThings used in Xunit unit tests

I usually TimeThings in my Xunit unit tests, and the code below shows a basic use, but you be aware most unit tests run in parallel, which affect the time a process takes - see this section on how to run your unit test to get a "correct" time).

public class TestTimeThings(ITestOutputHelper output) 
//The ITestOutputHelper is Xunit's way to return a string to your Test Explorer
{
    [Fact]
    public void TestWithTimeThings()
    {
        //SETUP                  
        //your test setup

        //ATTEMPT
        using (new TimeThings(output))
        {
            //your process you need to test and 
        }

        //VERIFY
        //your test checks
    }

The default message returns a string with a time, e.g., "took 1.64 ms.", which comes up in your Test Explorer (assuming that the your process doesn't throw an Exception).

_NOTE: The time in the string is "scaled" , i.e. it will look at the time and give you the time in _

to make it easier to understand

The TimeThings class has some optional parameters you can use, like message and numRuns - see the

/// <summary>
/// This will measure the time it took from this class being created to it being disposed and writes out to xUnit ITestOutputHelper
/// </summary>
/// <param name="output">On dispose it will write the result to the output</param>
/// <param name="message">Optional: a string to show in the result. Useful if you have multiple timing in one unit test.</param>
/// <param name="numRuns">Optional: if the timing covers multiple runs of something, then set numRuns to the number of runs and it will give you the average per run</param>
public TimeThings(ITestOutputHelper output, string message = "", int numRuns = 0)
{
   // rest of code left out

So, if you used the TimeThings class with new TimeThings(output, "read data", 500), you would get the string

500 x read data took 23.45 ms., ave. per run = 46.90 us.

TimeThings used outside of Xunit unit tests

There is a version of the TimeThings which return a TimeThingResult which contains

Clone this wiki locally