Optimizing .NET Code using Benchmarks

Page content

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,

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 from CardWriter.cs class.
  • Class Program - General purpose class with static main function that invokes BenchmarkRunner 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,

Benchmark Result

Report shows Memory Allocation as well as Execution time lines across Platform (.NET Framework Vesions) and parameters.

References:

Happy Coding !!