Table of Contents

Columns

A column is a column in the summary table.

Default columns

In this section, default columns (which be added to the Summary table by default) are presented. Some of columns are optional, i.e. they can be omitted (it depends on the measurements from the summary).

Target

There are 3 default columns which describes the target benchmark: Namespace, Type, Method. Namespace and Type will be omitted when all the benchmarks have the same namespace or type name. Method column always be a part of the summary table.

Job

There are many different job characteristics, but the summary includes only characteristics which has at least one non-default value.

Statistics

There are also a lot of different statistics which can be considered. It will be really hard to analyse the summary table, if all of the available statistics will be shown. Fortunately, BenchmarkDotNet has some heuristics for statistics columns and shows only important columns. For example, if all of the standard deviations are zero (we run our benchmarks against Dry job), this column will be omitted. The standard error will be shown only for cases when we are failed to achieve required accuracy level.

Only Mean will be always shown. If the distribution looks strange, BenchmarkDotNet could also print additional columns like Median or P95 (95th percentile).

If you need specific statistics, you always could add them manually.

Params

If you have params, the corresponded columns will be automatically added.

Diagnosers

If you turned on diagnosers which providers additional columns, they will be also included in the summary page.

Custom columns

Of course, you can define own custom columns and use it everywhere. Here is the definition of TagColumn:

using System;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Running;

namespace BenchmarkDotNet.Columns
{
    public class TagColumn : IColumn
    {
        private readonly Func<string, string> getTag;

        public string Id { get; }
        public string ColumnName { get; }

        public TagColumn(string columnName, Func<string, string> getTag)
        {
            this.getTag = getTag;
            ColumnName = columnName;
            Id = nameof(TagColumn) + "." + ColumnName;
        }

        public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) => false;
        public string GetValue(Summary summary, BenchmarkCase benchmarkCase) => getTag(benchmarkCase.Descriptor?.WorkloadMethod?.Name ?? "");

        public bool IsAvailable(Summary summary) => true;
        public bool AlwaysShow => true;
        public ColumnCategory Category => ColumnCategory.Custom;
        public int PriorityInCategory => 0;
        public bool IsNumeric => false;
        public UnitType UnitType => UnitType.Dimensionless;
        public string Legend => $"Custom '{ColumnName}' tag column";
        public string GetValue(Summary summary, BenchmarkCase benchmarkCase, SummaryStyle style) => GetValue(summary, benchmarkCase);
        public override string ToString() => ColumnName;
    }
}

Sample: IntroTagColumn

In the following example, we introduce two new columns which contains a tag based on a benchmark method name.

Source code

using System.Threading;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;

namespace BenchmarkDotNet.Samples
{
    // You can add custom tags per each method using Columns
    [Config(typeof(Config))]
    public class IntroTagColumn
    {
        private class Config : ManualConfig
        {
            public Config()
            {
                AddJob(Job.Dry);
                AddColumn(new TagColumn("Kind", name => name.Substring(0, 3)));
                AddColumn(new TagColumn("Number", name => name.Substring(3)));
            }
        }

        [Benchmark]
        public void Foo1() => Thread.Sleep(10);

        [Benchmark]
        public void Foo12() => Thread.Sleep(10);

        [Benchmark]
        public void Bar3() => Thread.Sleep(10);

        [Benchmark]
        public void Bar34() => Thread.Sleep(10);
    }
}

Output

| Method | Mean       | Kind | Number |
| ------ | ---------- | ---- | ------ |
| Bar34  | 10.3636 ms | Bar  | 34     |
| Bar3   | 10.4662 ms | Bar  | 3      |
| Foo12  | 10.1377 ms | Foo  | 12     |
| Foo1   | 10.2814 ms | Foo  | 1      |