
In this article, I will introduce the BenchmarkDotNet library and how to measure code performance with it, which will lead to sets of execution results and data related to your performance.
What is BenchmarkDotNet?
BenchamarkDotNet is a tool that allows us to analyze the performance of our application and anticipate problems that could delay production.
Our goal with this tool is to measure the performance of our code. NET is making an effort to make it as efficient as possible.
This package will generate an isolated project for each method that we mark with the Benchmark decorator, and will be in charge of carrying out for us, the launches of the project by executing it in several iterations.
The ability to run performance tests, extract results, and analyze them is possible with that.
All of it can be done in a few lines of code.
The tool will extract the report in various formats (CSV, HTML, etc.).
The data we will collect are those that the tool considers the most important.
For more information, it’s best to consult BenchmarkDotNet documentation.
The source code of this tool is open and can be consulted at this link.
To install the BenchmarkDotNet package in your project, you can either search for it using the NuGet Package Manager or run the command below using the command line. NET.
Install-Package BenchmarkDotNet
How to use it?
Once I have briefly explained what Benchmark consists of, I will try to explain its use with an example.
Let’s Start practice!, For the practical example, Let’s create a new Console-type project using Visual Studio 2022 called TestPerformanceWithBenchmarkDemo and a performance analysis will be performed between the different forms of string comparison. The comparison methods used are:
- Equality with ToUpper
- Equality with ToLower
- Equals with IgnoreCase
- Compare with IgnoreCase
The performance of this operation can vary significantly depending on the methods used, which could have a significant impact on scenarios with a high number of comparisons (like collections searches).
The class that contains the benchmarks is just below.
using BenchmarkDotNet.Attributes;
namespace TestPerformanceWithBenchmarkDemo
{
public class TestPerformanceWithBenchmark
{
private string Name1 = "Venu Thomas";
private string Name2 = "vEnU tHoMaS";
[Benchmark]
public bool IsEqualWithToUpper() => Name1.ToUpper() == Name2.ToUpper();
[Benchmark]
public bool IsEqualWithLower() => Name1.ToLower() == Name2.ToLower();
[Benchmark]
public bool IsEqualWithIgnoreCase() => Name1.Equals(Name2, StringComparison.OrdinalIgnoreCase);
[Benchmark]
public bool IsCompareWithIgnoreCase() => string.Compare(Name1, Name2, StringComparison.OrdinalIgnoreCase) == 0;
}
}
Please be aware that [Benchmark] annotations are used in the code above. BenchmarkDotNet will evaluate the performance of its executions by using them.
As we are in a Console project, we now just need to change the Program.cs file to be able to run the benchmarks.
using BenchmarkDotNet.Running;
using TestPerformanceWithBenchmarkDemo;
var summary = BenchmarkRunner.Run<TestPerformanceWithBenchmark>();
Once this is completed, we only need to execute the project to perform our test. But beware, it has to be in ‘Release’ to be able to measure the performance of the code with the compiler optimizations.
Once it is executed, it will show us the results in the console itself:

Performance of our project with BenchmarkDotNet
To be objective, I list the most important solutions related to the final result, even though there are other options.
From the best to the worst, we can see that this is the order of performance:
- Equals with IgnoreCase
- Compare with IgnoreCase
- Equality with ToUpper, Equality with ToLower
Now let’s include the RankColumn, Orderer and MemoryDiagnoser attributes at the top of the TestPerformanceWithBenchmark class.
using BenchmarkDotNet.Attributes;
namespace TestPerformanceWithBenchmarkDemo
{
[RankColumn]
[Orderer(BenchmarkDotNet.Order.SummaryOrderPolicy.FastestToSlowest)]
[MemoryDiagnoser]
public class TestPerformanceWithBenchmark
{
private string Name1 = "Venu Thomas";
private string Name2 = "vEnU tHoMaS";
[Benchmark]
public bool IsEqualWithToUpper() => Name1.ToUpper() == Name2.ToUpper();
[Benchmark]
public bool IsEqualWithLower() => Name1.ToLower() == Name2.ToLower();
[Benchmark]
public bool IsEqualWithIgnoreCase() => Name1.Equals(Name2, StringComparison.OrdinalIgnoreCase);
[Benchmark]
public bool IsCompareWithIgnoreCase() => string.Compare(Name1, Name2, StringComparison.OrdinalIgnoreCase) == 0;
}
}
As we can see in this code, I have also decorated the class with different attributes.
- RankColumn: Provide us with the range or position where the result was obtained.
- Orderer: Allows you to customize the order of the performance test result in the summary table. In our case, we sort the results from fastest to slowest. We can combine several orderings separated by commas.
- MemoryDiagnoser: Allows us to track the number of bytes assigned and the frequency of garbage collection. For more information, I suggest you read this post by Adam Sitnik
An extra column will be added to the output of the result to indicate which is method was faster. Run the TestPerformanceWithBenchmarkDemo process again in Release mode
The following is the result obtained:

Note that we now have the Rank column indicating that the IsEqualWithIgnoreCase method is in the first place indicating that it is faster.
This means that BenchmarkDotNet is a good tool for carrying out performance evaluations and that it provides a simple, cost-free way of making a decision about your application’s performance metrics.
If you would like to ask me questions, please feel free! I’ll always have my mailbox open. Whether you have a question or would like to simply say hello. I will do my utmost to respond!