"You can't improve what you don't measure." - someone once said. And he/she was right. We often find ourselves in a situation where a certain method or part of the code does not work as we want in terms of execution speed on the CPU, memory usage, and the like. In such cases, we approach code optimization. But in order to improve the parts of the code that are not good, it is necessary to measure the performance. You can use the BenchmarkDotNet library for that.
BenchmarkDotNet is an open-source, efficient .NET library that turns your methods into benchmarks, monitors them, and offers insights into the collected performance data. It takes care of all the best practices related to benchmarking, like:
To start using BenchmarkDotNet, you should install it via NuGet:
Install-Package BenchmarkDotNet
Write the code you want to benchmark in a method and annotate it with the [Benchmark] attribute.
using BenchmarkDotNet.Atrributes; public class MyBenchmarks{ [Benchmark] public void SomeBenchmark() { //Your code here... }}
To run the benchmarks, you create a new instance of the BenchmarkRunner class and call the Run method.
using BenchmarkDotNet.Running; class Program{ static void Main(string[] args) { var summary = BenchmarkRunner.Run<MyBenchmarks>(); }}
This will run the benchmark and print the results in the console. The summary object also contains the results, which can be used programmatically if needed.
What do the results look like?

BenchmarkDotNet provides a detailed summary including:
BenchmarkDotNet has a wealth of advanced features, including:
You can run benchmarks with different parameters to see how they affect performance.
using BenchmarkDotNet.Attributes; public class ParameterizedBenchmarks{ [Params(100, 200, 300)] public int N; [Benchmark] public in SumUpToN() { int sum = 0; for(int i=0; i < N; i++) sum+=i; return sum; }}
To run benchmarks against different .NET runtimes, you can use the [CoreJob, ClrJob, MonoJob] attributes. You'll also need to adjust your project file to target multiple frameworks. First, adjust your .csproj: < TargetFrameworks >net7.0;net6.0;net5.0</ TargetFrameworks > Then, in your benchmark class:
using BenchmarkDotNet.Attributes;using BenchmarkDotNet.Jobs; [CoreJob, ClrJob, MonoJob]public class MultiRuntimeBenchmarks{ [Benchmark] public void SomeBenchmark() { //Your code here... }}
You can create a custom configuration that controls the benchmarking process.
using BenchmarkDotNet.Configs;using BenchmarkDotNet.Jobs;using BenchmarkDotNet.Attributes; public class CustomConfig : ManualConfig{ public CustomConfig() { AddJob(Job.Default.WithWarmupCount(3).WithIterationCount(10)); }} [Config(typeof(CustomConfig))]public class CustomConfigurationBenchmarks{ [Benchmark] public void SomeBenchmark() { //Your code here... }}
To capture diagnostics like memory traffic or GC collections, you'll use the [MemoryDiagnoser] attribute. For more detailed diagnostics, you might consider other diagnosers available in BenchmarkDotNet, like [DisassemblyDiagnoser].
using BenchmarkDotNet.Attributes; [MemoryDiagnoser]public class MemoryDiagnosticsBenchmarks{ [Benchmark] public List<int> CreateList() { return new List<int> { 1, 2, 3, 4, 5 }; }}
BenchmarkDotNet is an open-source, efficient .NET library that turns your methods into benchmarks, monitors them, and offers insights into the collected performance data.
Basic Usage
Best Practices
That's all from me for today.
Want to enforce clean code automatically? My Pragmatic .NET Code Rules course shows you how to set up analyzers, CI quality gates, and architecture tests - a production-ready system that keeps your codebase clean without manual reviews. Or grab the free Starter Kit to try it out.
Stop arguing about code style. In this course you get a production-proven setup with analyzers, CI quality gates, and architecture tests — the exact system I use in real projects. Join here.
Not sure yet? Grab the free Starter Kit — a drop-in setup with the essentials from Module 01.
Design Patterns that Deliver — Solve real problems with 5 battle-tested patterns (Builder, Decorator, Strategy, Adapter, Mediator) using practical, real-world examples. Trusted by 650+ developers.
Just getting started? Design Patterns Simplified covers 10 essential patterns in a beginner-friendly, 30-page guide for just $9.95.
Every Monday morning, I share 1 actionable tip on C#, .NET & Architecture that you can use right away. Join here.
Join 20,000+ subscribers who mass-improve their .NET skills with actionable tips on C#, Software Architecture & Best Practices.
Subscribe to the TheCodeMan.net and be among the 20,000+ subscribers gaining practical tips and resources to enhance your .NET expertise.