Performance Measurement With BenchmarkDotNet in C#

Introduction
Oftentimes, we need a way to measure how well a piece of code does, how fast it runs, how much memory it consumes, etc. All these questions fall under the umbrella of performance measurement, and in this article, we will be looking at that.
We would be using Benchmarkdotnet for measuring our performance. Benchmarkdotnet is a free tool that can be gotten from the NuGet repository.
The source code for this project is freely available here.
Let's get started!
Installing BenchmarkDotNet
To use benchmarkdotnet we must first install it in our project.
Step 1: Create a new console project
Create a new console project using Visual Studio, VS code, CLI, Rider, or any preferred tool of choice. I will be using Rider for our demo.

Step 2: Install the package
Search for Benchmarkdotnet on the NuGet repository and Install it in the newly created project.

Measuring Performance
For measuring performance, we would compare the operations of concatenating strings using the += operator versus using the StringBuilder class.
Step 1: Creating our class
Create a class StringConcatenation class with the following methods included.
public void BuildStringsWithConcatenation()
{
var output = String.Empty;
for (var i = 0; i < 100; i++)
{
output += "test";
}
}
public void BuildStringsWithStringBuilder()
{
var output = String.Empty;
var builder = new StringBuilder();
for (var i = 0; i < 100; i++)
{
builder.Append("test");
}
output = builder.ToString();
}
Step 2: Namespace inclusion
Include the BenchmarkDotNet.Attributes namespace in the StringConcatenation class
using BenchmarkDotNet.Attributes;
Step 3: Attribute decorations
Add the [Benchmark] attribute to each of the created methods.
Optional: You could also add the [Orderer(SummaryOrderPolicy.FastestToSlowest)] and [MemoryDiagnoser()] attributes to the class. The result is that the result set would be ordered from the fastest to the slowest, and the memory consumption of each method would also be included.
By the time you're done, the code should look like this:
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
namespace BenchMark.NET;
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[MemoryDiagnoser()]
public class StringConcatenation
{
[Benchmark]
public void BuildStringsWithConcatenation()
{
var output = String.Empty;
for (var i = 0; i < 100; i++)
{
output += "test";
}
}
[Benchmark]
public void BuildStringsWithStringBuilder()
{
var output = String.Empty;
var builder = new StringBuilder();
for (var i = 0; i < 100; i++)
{
builder.Append("test");
}
output = builder.ToString();
}
}
Step 4: Bootstrapping our benchmarks
Call BenchmarkRunner.Run
In Program.cs, add the following line of code:
using BenchMark.NET;
using BenchmarkDotNet.Running;
BenchmarkRunner.Run(typeof(StringConcatenation));
Step 5: Running the project
Run the project in Release mode. We are not running it in Debug mode because want our result to be as close to the production scenario as possible. On the console output, you would receive something similar to this:

Conclusion
In conclusion, we see that the BuildStringsWithStringBuilder method completed at 628.4 ns and used 2.23 KB of memory, performing better than the BuildStringsWithConcatenation method, which finished at 3,328.6 ns and used 41.77 KB of memory. This is expected because the StringBuilder class presents a more effective way of building strings.




