Edit

Share via


Analyze BenchmarkDotNet data in Visual Studio

You can use the profiling tools to collect and view BenchmarkDotNet data in Visual Studio. BenchmarkDotNet is an open-source .NET library designed for performance benchmarking. It automates the process of measuring and comparing the execution time, memory usage, and other performance metrics of your .NET code in a reliable and repeatable way.

You use BenchmarkDotNet by installing required NuGet packages in your project and then adding attributes to your code that match the type of performance information you are interested in.

Prerequisites

Set up your project

The benchmark attributes must be added to a .NET console application. The attributes can be added to wrapper functions that reference other project types.

To prepare your project for BenchmarkDotNet support, use one of the following methods:

  • Open an existing console project or create a new console project. In this scenario, you manually add BenchmarkDotNet support.

  • Use the Benchmark Project template. Some of the steps described in this article are required only when you manually add BenchmarkDotNet support.

    The Benchmark Project template generates a fully integrated BenchmarkDotNet project with built-in support for CPU Usage profiling and Copilot insights. To use the template, select Profiling from the project types list when you create a new project, and then choose Benchmark Project. For information about attributes, see Attribute your code.

Screenshot of BenchmarkDotNet template in Visual Studio.

Create a console project or use an existing console project.

The benchmark attributes must be added to a .NET console application. The attributes can be added to wrapper functions that reference other project types.

Attribute your code

When you add a BenchmarkDotNet diagnoser to your benchmark classes as an attribute, you configure the app to generate a .diagsession file after the benchmarks run. You can then open the .diagsession file in Visual Studio and view profiling data for the benchmarks.

The following diagnosers are supported:

  • CPUUsageDiagnoser
  • DatabaseDiagnoser
  • DotNetCountersDiagnoser
  • EventsDiagnoser
  • FileIODiagnoser

Each diagnoser generates performance data related to that diagnoser. For example, the CPUUsageDiagnoser generates a .diagsession file with CPU data in it, and the DatabaseDiagnoser generates a .diagsession file with data on database operations. Limitations correspond to the associated profiling tool. For example, the profiler's Database tool works on ADO.NET or Entity Framework Core.

To attribute your code for diagnosers and benchmarks:

  1. Add the diagnoser name as an attribute to the class that contains the benchmarks for which you want to generate data.

  2. Add the Benchmark attribute to the methods that you want to test for performance.

    For example, you can use the following code for the CPUUsageDiagnoser.

    If you're using the Benchmark Project template, sample code is already provided in the template. If you're manually adding BenchmarkDotNet support, you can use the following example code.

    using System;
    using System.Security.Cryptography;
    using BenchmarkDotNet.Attributes;
    using BenchmarkDotNet.Running;
    using Microsoft.VSDiagnostics;
    
    namespace MyBenchmarks
    {
        [CPUUsageDiagnoser]
        public class Md5VsSha256
        {
            private const int N = 10000;
            private readonly byte[] data;
    
            private readonly SHA256 sha256 = SHA256.Create();
            private readonly MD5 md5 = MD5.Create();
    
            public Md5VsSha256()
            {
                data = new byte[N];
                new Random(42).NextBytes(data);
            }
    
            [Benchmark]
            public byte[] Sha256() => sha256.ComputeHash(data);
    
            [Benchmark]
            public byte[] Md5() => md5.ComputeHash(data);
        }
    
        public class Program
        {
            public static void Main(string[] args)
            {
                var summary = BenchmarkRunner.Run(typeof(Program).Assembly);
            }
        }
    }
    

Collect and view Benchmark.NET data

  1. Set your build to a Release build instead of a Debug build.

  2. Run the application to generate the .diagsession file.

    Check the console output to get the location of the file. For example:

    // * Diagnostic Output - VSDiagnosticsDiagnoser * 
    Collection result moved to 'BenchmarkDotNet_Md5VsSha256_20231218_123326.diagsession'.
    Session : {7f38bcc2-c692-4266-aa24-b12bc5325ea4}
      Stopped
    Exported diagsession file: *.diagsession
    
  3. In Visual Studio, select File > Open > File and navigate to the location of the .diagsession file, and then select and open the file.

  4. Select the Benchmarks tab to view data for the BenchmarkDotNet benchmarks.

    Screenshot of BenchmarkDotNet data in Visual Studio.

    For more information about the results in the Benchmarks tab, see BenchmarkDotNet documentation.

  5. Right-click a row in the results and choose Select time range to sync the timeline graph with the benchmark.

  6. Select one of the available tabs such as CPU Usage or Allocations.

    Depending on the diagnoser you used to collect data, you can gain insights related to memory allocation, CPU usage, counters, and other performance data. To analyze memory allocations, use the built-in MemoryDiagnoser by adding the [MemoryDiagnoser] attribute. For more information, see Diagnosers.

    Note

    The profiler supports only the [MemoryDiagnoser] and the diagnosers listed previously in this article.

    For an example of using the profiler to analyze memory allocations, see the blog post Benchmarking with Visual Studio Profiler.

    To analyze data related to other tabs such as CPU Usage, see the corresponding articles in the profiling documentation.

Optimize with Copilot

You can trigger CPU and memory allocation optimizations for your BenchmarkDotNet benchmarks directly from the editor using CodeLens. This makes performance tuning more accessible and seamless, helping you find and fix CPU and memory allocation issues right where you code.

Select the CodeLens indicator above your benchmark and then select the option Optimize Allocations with Copilot.

Screenshot of optimizing with Copilot.