Table of Contents

Configs

Config is a set of so called jobs, columns, exporters, loggers, diagnosers, analysers, validators that help you to build your benchmark.

Built-in configuration

There are two built-in ways to set your config:

Object style

[Config(typeof(Config))]
public class MyClassWithBenchmarks
{
    private class Config : ManualConfig
    {
        public Config()
        {
            AddJob(new Job1(), new Job2());
            AddColumn(new Column1(), new Column2());
            AddColumnProvider(new ColumnProvider1(), new ColumnProvider2());
            AddExporter(new Exporter1(), new Exporter2());
            AddLogger(new Logger1(), new Logger2());
            AddDiagnoser(new Diagnoser1(), new Diagnoser2());
            AddAnalyser(new Analyser1(), new Analyser2());
            AddValidator(new Validator2(),new Validator2());
            AddHardwareCounters(HardwareCounter enum1, HardwareCounter enum2);
            AddFilter(new Filter1(), new Filter2());
            AddLogicalGroupRules(BenchmarkLogicalGroupRule enum1, BenchmarkLogicalGroupRule enum2);
        }
    }
    
    [Benchmark]
    public void Benchmark1()
    {
    }
    
    [Benchmark]
    public void Benchmark2()
    {
    }
}

Sample: IntroConfigSource

You can define own config attribute.

Source code

using System;
using System.Linq;
using System.Threading;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;

namespace BenchmarkDotNet.Samples
{
    [MyConfigSource(Jit.LegacyJit, Jit.RyuJit)]
    public class IntroConfigSource
    {
        /// <summary>
        /// Dry-x64 jobs for specific jits
        /// </summary>
        private class MyConfigSourceAttribute : Attribute, IConfigSource
        {
            public IConfig Config { get; }

            public MyConfigSourceAttribute(params Jit[] jits)
            {
                var jobs = jits
                    .Select(jit => new Job(Job.Dry) { Environment = { Jit = jit, Platform = Platform.X64 } })
                    .ToArray();
                Config = ManualConfig.CreateEmpty().AddJob(jobs);
            }
        }

        [Benchmark]
        public void Foo()
        {
            Thread.Sleep(10);
        }
    }
}

Sample: IntroConfigUnion

Source code

using System.Threading;
using BenchmarkDotNet.Analysers;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Exporters.Csv;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;

namespace BenchmarkDotNet.Samples
{
    [Config(typeof(Config))]
    public class IntroConfigUnion
    {
        private class Config : ManualConfig
        {
            public Config()
            {
                AddJob(Job.Dry);
                AddLogger(ConsoleLogger.Default);
                AddColumn(TargetMethodColumn.Method, StatisticColumn.Max);
                AddExporter(RPlotExporter.Default, CsvExporter.Default);
                AddAnalyser(EnvironmentAnalyser.Default);
                UnionRule = ConfigUnionRule.AlwaysUseLocal;
            }
        }

        [Benchmark]
        public void Foo()
        {
            Thread.Sleep(10);
        }
    }
}

Sample: IntroFluentConfigBuilder

There is no need to create new Config type, you can simply use fluent interface.

Source code

using System;
using System.Security.Cryptography;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Validators;

namespace BenchmarkDotNet.Samples
{
    public class Algo_Md5VsSha256
    {
        private const int N = 10000;
        private readonly byte[] data;

        private readonly MD5 md5 = MD5.Create();
        private readonly SHA256 sha256 = SHA256.Create();

        public Algo_Md5VsSha256()
        {
            data = new byte[N];
            new Random(42).NextBytes(data);
        }

        [Benchmark(Baseline = true)]
        public byte[] Md5() => md5.ComputeHash(data);

        [Benchmark]
        public byte[] Sha256() => sha256.ComputeHash(data);
    }

    public class IntroFluentConfigBuilder
    {
        public static void Run()
        {
            BenchmarkRunner
                .Run<Algo_Md5VsSha256>(
                    DefaultConfig.Instance
                        .AddJob(Job.Default.WithRuntime(ClrRuntime.Net462))
                        .AddJob(Job.Default.WithRuntime(CoreRuntime.Core21))
                        .AddValidator(ExecutionValidator.FailOnError));
        }
    }
}