How to benchmark different .NET versions

With the famous BenchmarkDotNet library you can benchmark a lot - but it doesn't stop with a single .NET version. You can benchmark multiple versions of the same code that targets different runtimes!

The setup

To run multiple versions of your code, you have to select multiple target frameworks in your csproj file:

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <LangVersion>preview</LangVersion>
        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
        <TargetFrameworks>net7.0;net8.0</TargetFrameworks>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="BenchmarkDotNet" Version="0.13.6" />
    </ItemGroup>

</Project>

Then inside your BenchmarkDotNet test you can define via the SimpleJobAttribute the target runtime.

[SimpleJob(RuntimeMoniker.Net70, baseline: true)]
[SimpleJob(RuntimeMoniker.Net80)]
[MemoryDiagnoser]
public class InterpolatedEnumBenchmark
{
    [Benchmark]
    public string Interpolated()
        => $"{Weekdays.Monday} {Weekdays.Tuesday} {Weekdays.Wednesday} {Weekdays.Thursday} {Weekdays.Friday} {Weekdays.Saturday} {Weekdays.Sunday}";
}

public enum Weekdays
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

The result will look like this:

BenchmarkDotNet v0.13.6, macOS Ventura 13.4.1 (22F82) [Darwin 22.5.0]
Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
.NET SDK 8.0.100-preview.6.23330.14
  [Host]   : .NET 7.0.5 (7.0.523.17405), Arm64 RyuJIT AdvSIMD
  .NET 7.0 : .NET 7.0.5 (7.0.523.17405), Arm64 RyuJIT AdvSIMD
  .NET 8.0 : .NET 8.0.0 (8.0.23.32907), Arm64 RyuJIT AdvSIMD


|       Method |      Job |  Runtime |      Mean |    Error |   StdDev | Ratio |   Gen0 | Allocated | Alloc Ratio |
|------------- |--------- |--------- |----------:|---------:|---------:|------:|-------:|----------:|------------:|
| Interpolated | .NET 7.0 | .NET 7.0 | 148.66 ns | 2.008 ns | 1.780 ns |  1.00 | 0.0484 |     304 B |        1.00 |
| Interpolated | .NET 8.0 | .NET 8.0 |  61.37 ns | 0.888 ns | 0.831 ns |  0.41 | 0.0216 |     136 B |        0.45 |

Logging Source Code Generators

Since .NET6 we have the possibility to define an easy way of logging common statements:

Meet Compile-time logging source generators. This article will show why we have them and how to use them. Of course a smaller benchmark will also follow.

From Zero to Production - Generate everything with a single button

This blog post will show you how to setup, from scratch, your GitHub repository so you can in a matter of a single click:

  • Run tests and build your application
  • Release the application for example to nuget
  • Create a Release on GitHub with Release notes
  • Update the documentation utilizing GitHub Pages and DocFx

Therefore we will build a "template" repository you can take as a foundation.

LINQ on steroids with SIMD

In this blog post, we will explore the use of SIMD instructions to speed up LINQ queries. We will use the Vector type of performing SIMD operations on arrays of data. We will also use the BenchmarkDotNet library to measure the performance of our code. We will also see how this works hand in hand with the new "generic math" feature of C# 10.

An error has occurred. This application may no longer respond until reloaded. Reload x