Optimizing dotnet source code using benchmarking technique using BenchmarkDotNet - Part 1


The benchmarking technique aids in calculating the performance metrics of a single or multiple sections of code in your application. Benchmark can assist you in identifying the parts of your source code that require optimization.


What's a Benchmark?

A benchmark is a basic test that delivers a set of quantifiable statistics that can assist you in determining whether or not a modification to your code has increased, decreased, or had no influence on the overall performance. It is essential to have an understanding of the performance metrics that are associated with the methods that make up your application to make use of them during the process of code optimization.


Benefits of Benchmarking a source code

  • Benchmarking is the process of comparing the performance of code snippets, usually against a predefined baseline.
  • Benchmarking can assist in identifying performance bottlenecks in an application. (By identifying bottlenecks, you can determine the changes needed in your source code to improve the application's performance and scalability.)



BenchmarkDotNet

BenchmarkDotNet helps you to transform methods into benchmarks, track their performance, and share reproducible measurement experiments. 

This is an open-source library that can convert your.NET methods into benchmarks, monitor those methods, and gain insights into the performance data collected. It is compatible with both.NET Framework and.NET Core applications. BenchmarkDotNet can quickly convert your methods into benchmarks, run those benchmarks, and retrieve the benchmarking results. An operation in BenchmarkDotNet terminology involves executing a method decorated with the Benchmark attribute.


Steps for benchmarking code using BenchmakDotNet

To run BenchmarkDotNet in your .NET Framework or .NET Core application, you must follow these steps:

  1. Add the necessary NuGet package
  2. Add Benchmark attributes to your methods
  3. Create a BenchmarkRunner instance
  4. Run the application in Release mode


Practical

Now we can see how to config BenchmarkDotNet library in your asp.net core project and try to retrieve some measurements on the selected Scenario.


Considering Scenario - string builder vs. string performance.

To learn the BenchmarkDotNet library with the asp.net core project, a simple development scenario is utilized here.


 We will compare the string builder and string in terms of performance. Here, we look at how long it takes and how much memory it takes to append 100 characters into a single string. 


First, let's create a console application and install the BenchmarkDotNet NuGet package.


Create Dotnet 6 Console project and add BenchmarkDotNet library

Let’s open Visual Studio 2022 and create a .NET 6 based console application. I named it "StringBuilderVsStringBenchmarkDotnet".



This is the time to install the BenchmarkDotNet NuGet package into my console application.  You can use the command given below to add the package to the console app. This command should be executed from the project directory path.

dotnet add package BenchmarkDotNet

You can also add NuGet references using Manage NuGet Packages. It will open the dialog as shown below. Search for BenchmarkDotNet and install the package.
Note: Here, I am using Rider as my main IDE.




Benchmark Code

This is the complete code for the run benchmark methods. Here we implemented two scenarios of methods.

These couple of methods we want to benchmark. For that, we simply add [Benchmark] annotation on top of the method. It is the sign for considering to BenchmarkRunner class.

Also [MemoryDiagnoser()] annotation helps to identify memory heap of a method.


Running benchmark project

Running the benchmarking application in release configuration is a requirement for benchmarking. When building the project, you should ideally have the optimize option set to true in csproj or the CSC command line.

Additionally, the process shouldn't have a debugger attached to it. This implies that we have two choices whenever we want to run the benchmarking application.

Release mode

  • Run the application from Visual Studio/Rider by using Debug -> Start Without Debugging (keyboard shortcut CTRL + F5 ). The configuration should be set to release.
  • OR the other option is to run the application using dotnet CLI. While using dotnet run command, we should ensure that we add -c release switch to the command.

    dotnet run -p StringBuilderVsStringBenchmarkDotnet.csproj -c Release

Running this straightforward app might take a few seconds. This is due to BenchmarkDotNet's repeated launch of the benchmark process.

Result of the test

We can then look at the outcomes below. Here is the summary I received on my computer for your reference.


NOTE: Be aware that in order to perform a benchmark, we must ensure that all programs other than the benchmark process and the default OS processes are turned off. Running a benchmark while working in Visual Studio simultaneously can have a negative impact on the benchmark results.

Considering the result set, we should consider two parameters:
  1. Mean parameter
  2. Allocated parameter
The mean parameter describes the average time it takes the method to run.

An allocated parameter describes the average allocation of the heap in memory while the method is running.


Conclusion

As we know, in programming technics,  We get the expected result from the application.

StringBuilder shows much-improved performance than the string concatenation. Average execution time and heap are also pretty low than the string concatenation. 


This article does not cover all of the available features and customization options. However, it should help you get started with this package. If you want to learn more, check out their documentation.


My sample repository

https://github.com/csandun/StringBuilderVsStringBenchmarkDotnet/


Resources

  1. Intro to Benchmark.net - How To Benchmark C# Code 
  2. Documentation 
  3. GitHub Repo


I hope you find this content helpful. Keep touching my diaries. Learn something new. Comment your thoughts and share the content.


Thank you.! 

Have an incredible coding journey. 

See you soon. ✌✌