Quick microbenchmarks in Visual Studio with Code Snippets

Stephen Toub - MSFT

Parallelism is all about performance.  After all, in the majority of cases, introducing parallelism into code adds some level of complexity, and the primary reason we’re ok with that additional complexity is because we get great performance enhancements as a result.  As such, as we develop our parallel runtimes and libraries to help others parallelize their code, we pay a lot of attention to what things cost, ensuring that we have as little overhead as possible in our libraries so that users of our libraries get the most benefit out of their parallelization.

Given that, often while coding I’ll find myself wondering what a particular operation costs. More often than not, I’ll have multiple ways I can potentially do something, and I’m interested in understanding if there’s any significant difference between the approaches that could have a non-negligible impact on the performance of my code.  I found myself writing the same boilerplate code over and over in Visual Studio, setting up a stopwatch, writing long loops to invoke each of the two operations, performing some basic statistics at the end, etc.  Then I realized that I could save all of that time if I just created a Code Snippet for this in Visual Studio.

With my snippet, I now just start typing “perfcomp” into the Visual Studio editor:

image

and when I tab-tab to expand the snippet, I get code like the following:

var sw = new Stopwatch();

const int ITERS = 1000000;

while (true)

{

    Console.Write(“A: “);

    sw.Restart();

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

    {

        // Operation A

    }

    var elapsedA = sw.Elapsed;

    Console.WriteLine(elapsedA);

 

    GC.Collect();

    GC.WaitForPendingFinalizers();

    GC.Collect();

 

    Console.Write(“B: “);

    sw.Restart();

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

    {

        // Operation B

    }

    var elapsedB = sw.Elapsed;

    Console.WriteLine(elapsedB);

 

    GC.Collect();

    GC.WaitForPendingFinalizers();

    GC.Collect();

 

    Console.WriteLine(“A/B     : {0}”,

        elapsedA.TotalMilliseconds /

        elapsedB.TotalMilliseconds);

    Console.WriteLine(“B/A     : {0}”,

        elapsedB.TotalMilliseconds /

        elapsedA.TotalMilliseconds);

    Console.WriteLine(“(A-B)/A : {0}”,

        Math.Abs((elapsedA.TotalMilliseconds –

                  elapsedB.TotalMilliseconds) /

                 elapsedA.TotalMilliseconds));

    Console.WriteLine(“(B-A)/B : {0}”,

        Math.Abs((elapsedB.TotalMilliseconds –

                  elapsedA.TotalMilliseconds) /

                 elapsedB.TotalMilliseconds));

    Console.WriteLine();

 

    Console.ReadLine();

}

I can then easily substitute the two operations I want to test for “Operation A” and “Operation B”, and quickly get some basic comparisons about their performance.  The whole thing is wrapped in a loop so that I can easily run multiple comparisons, which also helps to avoid any discrepancies that may arise from first-time use.

To install this snippet, unzip the PerfComparison.snippet file from the attached file, and then add it in Visual Studio via the Code Snippets Manager available from the Tools menu.

I hope it’s helpful.

PerfComparison.zip

0 comments

Discussion is closed.

Feedback usabilla icon