Benchmark: La misurazione della performance

Chi mi segue e/o mi conosce ha ben presente che per me scrivere codice non significa farlo andare. Per me scrivere codice significa farlo andare e bene. Per questo punto molta attenzione alle performance e l’utilizzo di benchmark viene spesso in aiuto. Prima di cominciare, vi consiglio di creare una ConsoleApp per eseguire il tutto ed agganciare i vostri componenti con codice/logiche.

BenchmarkDotNet

Personalmente per scrivere i benchmark del codice utilizzo BenchmarkDotNet. Per usarlo vi bastera’ installarlo tramite Nuget

1
PM > Install-Package BenchmarkDotNet 

oppure

1
dotnet add package BenchmarkDotNet 

Una volta installato siamo pronti ad utilizzarlo col nostro codice. Come?

Creazione Benchmark

Per procedere alla creazione del nostro Benchmark non dovremo fare altro che creare una nuova classe dedicata aggiungendo i seguenti using. A dire il vero quello che serve sicuro e’ BenchmarkDotNet.Attributes. L’aggiunta di Linq e’ solo per il mio esempio.

1
2
using BenchmarkDotNet.Attributes;
using System.Linq;

Come creo la classe? Ecco un breve template d’esempio.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[AllCategoriesFilter]
[AllStatisticsColumn]
public class BenchmarkDotNetTest
{
    [Benchmark]
    public void DoSomethingOne()
    {
        var items = Enumerable.Range(1, 1000);
    }

    [Benchmark]
    public void DoSomethingTwo()
    {
        var items = Enumerable.Range(1, 1000).ToList();
    }
}

Come avrete notato due metodi sono entrambi marcati con l’attributo [Benchmark].

Esecuzione Benchmark

Per eseguire la batteria di Benchmark presenti in una classe dovremmo (in una nuova classe) scrivere la seguente istruzione:

1
using BenchmarkDotNet.Running;
1
var benchmark = BenchmarkRunner.Run<BenchmarkDotNetTest>();

ATTENZIONE: Per eseguire il tutto dovrete essere in modalita’ Release

A questo punto non ci resta che aspettare il completamento della batteria di Benchmark ed andare a vedere i risultati. Come farlo?

  • Avviando i test verra’ mostrata una console coi risultati live
  • Nella cartella bin\Release ( ed entrando in net5.0 nel mio caso) troverete BenchmarkDotNet.Artifacts\results

Vi mostro il risultato dei Benchmark appena eseguiti

1
2
3
4
5
6
7
8

BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19041.928 (2004/?/20H1)
Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=5.0.202
  [Host]     : .NET Core 5.0.5 (CoreCLR 5.0.521.16609, CoreFX 5.0.521.16609), X64 RyuJIT  [AttachedDebugger]
  DefaultJob : .NET Core 5.0.5 (CoreCLR 5.0.521.16609, CoreFX 5.0.521.16609), X64 RyuJIT


MethodMeanErrorStdDevStdErrMedianMinQ1Q3MaxOp/s
DoSomethingOne26.03 ns0.538 ns0.477 ns0.128 ns25.92 ns25.55 ns25.64 ns26.14 ns27.15 ns38,422,919.6
DoSomethingTwo3,538.31 ns517.654 ns1,526.313 ns152.631 ns2,554.10 ns2,359.16 ns2,470.42 ns5,744.71 ns6,168.55 ns282,621.0

Benchmark Debug Mode

Nel punto precedente ho specificato che per l’esecuzione del Benchmark dovete essere in modalita’ Release. Cosa succede se mi dimentico la modalita’ Debug?

// Validating benchmarks:

Assembly ConsoleApp3 which defines benchmarks is non-optimized

Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE.

If you want to debug the benchmarks, please see https://benchmarkdotnet.org/articles/guides/troubleshooting.html#debugging-benchmarks.

Ecco, come avrete notato e’ impossibile dimenticarsi di passare alla modalita’ corretta. Tranquilli, il messaggio appare in rosso e quindi fare gli indifferenti e’ impossibile!