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 |
Links
- Columns
- The permanent link to this sample: BenchmarkDotNet.Samples.IntroTagColumn