Optimizing .NET Code using Benchmarks
Background
Oftentimes, we come across situation where code does not perform as per expectation. What is typically approch to address it,
- Performance Testing - Visual Studio Load Tests or Third party tools like Locust, Vegeta, Gatling etc.
- Visual Studio Diagnostics Tools Or
- Use tools like Perfview/dotTrace/dotMemory to diagnose bottlenecks
What if it is possible to Benchmark code for,
- Set of varying parameter(s)
- Different runtimes (.NET Framework versions, .NET core, Mono etc.) with option to Benchmark it
- Observe Memory Allocations for diagnostics
- Get Detailed report on execution timeline
- Have it as part of test suite so that it can be easily executed with every iteration involving optimized code to get immediate feedback
Enter BenchmarkDotNet, a Powerful .NET library for benchmarking. It is used by DotNET Team, Roslyn, ASP.NET Core and many other projects.
Though Benchmarkdotnet.org has nice documentation with detailed examples, Below we will look at how to benchmark a code which is aimed at dumping in-memory list of objects to a delimited file. In real-world scenario, the list of objects could be retrieved from external data store.
So Lets Start.
Approach
We will have below before we proceed with using BenchmarkDotNet
- Dummy class that represents Data Structure to be dumped to a file,
Refer Gist here
Class
CardWriter.cs
that generates file using,- Using StreamWriter with Buffer
- Using Stringbuilder and StreamWriter
- Using Open source CSVHelper library
Refer Gist here
- Now, let us write code to benchmark above functions with Memory Diagnostics,
Refer Gist here
Above code,
- Class
FileGeneratorBenchmark
- This class uses BenchmarkDotNET attributes to decorate set of functions which in turn call functions fromCardWriter.cs
class. - Class
Program
- General purpose class with staticmain
function that invokesBenchmarkRunner
to execute benchmarks.
It is required to run these benchmarks in Release
mode or else BenchmarkDotNet will alert about the same. After running the benchmark, It will generate detailed report like below,
Report shows Memory Allocation as well as Execution time lines across Platform (.NET Framework Vesions) and parameters.
References:
Happy Coding !!