Skip to content

Commit 972fee7

Browse files
Big refactoring
1 parent 0231157 commit 972fee7

File tree

226 files changed

+3515
-2136
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

226 files changed

+3515
-2136
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,5 @@ docs/apihtml
4343
**/project.lock.json
4444
tests/output/*
4545
.vs/restore.dg
46-
BDN.Auto
46+
BDN.Generated
4747
BenchmarkDotNet.Samples/Properties/launchSettings.json

BenchmarkDotNet.sln.DotSettings

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,31 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2-
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_METHOD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">True</s:Boolean>
2+
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=95F5D645_002D19E3_002D432F_002D95D4_002DC5EA374DD15B_002Fd_003ATemplates/@EntryIndexedValue">ExplicitlyExcluded</s:String>
3+
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToReturnStatement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
4+
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InvertIf/@EntryIndexedValue">DO_NOT_SHOW</s:String>
5+
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestBaseTypeForParameter/@EntryIndexedValue">DO_NOT_SHOW</s:String>
6+
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_METHOD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
37
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_SINGLE_LINE_ARRAY_INITIALIZER_BRACES/@EntryValue">True</s:Boolean>
4-
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GC/@EntryIndexedValue">GC</s:String></wpf:ResourceDictionary>
8+
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">160</s:Int64>
9+
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
10+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=DECLSPEC_005FPROPERTY/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
11+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=ENUM/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
12+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=ENUMERATOR/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
13+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=GETTER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
14+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=GLOBAL_005FFUNCTION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
15+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=GLOBAL_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
16+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=LOCAL_005FTYPEDEF/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
17+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=LOCAL_005FVARIABLE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
18+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=NAMESPACE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
19+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=PARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
20+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=SETTER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="set_" Suffix="" Style="aa_bb" /&gt;</s:String>
21+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=STRUCT/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
22+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=STRUCT_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="_" Style="aa_bb" /&gt;</s:String>
23+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=STRUCT_005FMETHODS/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
24+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=TEMPLATE_005FPARAMETER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
25+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=TYPEDEF/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
26+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
27+
<s:String x:Key="/Default/CodeStyle/Naming/CppNaming/UserRules/=UNION_005FMEMBER/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" /&gt;</s:String>
28+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GC/@EntryIndexedValue">GC</s:String>
29+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
30+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
31+
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

docs/guide/Configs/Columns.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Columns
2+
3+
A *column* is a column in the summary table.
4+
5+
## Default columns
6+
7+
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 ommited (it depends on the measurements from the summary).
8+
9+
### Target
10+
11+
There are 3 default columns which describes the target benchmark: `Namespace`, `Type`, `Method`. `Namespace` and `Type` will be ommited when all the benchmarks have the same namespace or type name. `Method` column always be a part of the summary table.
12+
13+
### Job
14+
15+
There are many different job characteristics, but the summary includes only characteristics which has at least one non-default value.
16+
17+
### Statistics
18+
There are also a lot of different statistics which can be considered. It will be really hard to analyze the summary table, if all of the available statistics will be shown. Fortunally, BenchmarkDotNet has some heuristics for statistics columns and shows only important columns. For example, if all of the standard deviations is 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 achive required accurancy level.
19+
20+
Only `Mean` will be always shown. If the distribution looks strange, BenchmarkDotNet could also print additional columns like `Median` or `P95` (95th percentile).
21+
22+
If you need specific statistics, you always could add them manually.
23+
24+
### Params
25+
If you have `params`, the corresponded columns will be automatically added.
26+
27+
### Diagnosers
28+
If you turned on diagnosers which providers additional columns, they will be also included in the summary page.
29+
30+
## Optional columns
31+
32+
### TagColumns
33+
34+
You can also define own columns. In the following example, we introduce two new columns which contains a tag based on a benchmark method name:
35+
36+
```cs
37+
[Config(typeof(Config))]
38+
public class IntroTags
39+
{
40+
private class Config : ManualConfig
41+
{
42+
public Config()
43+
{
44+
// You can add custom tags per each method using Columns
45+
Add(new TagColumn("Kind", name => name.Substring(0, 3)));
46+
Add(new TagColumn("Number", name => name.Substring(3)));
47+
}
48+
}
49+
50+
[Benchmark] public void Foo1() { /* ... */ }
51+
[Benchmark] public void Foo12() { /* ... */ }
52+
[Benchmark] public void Bar3() { /* ... */ }
53+
[Benchmark] public void Bar34() { /* ... */ }
54+
}
55+
56+
```
57+
Result:
58+
59+
| Method | Median | StdDev | Foo or Bar | Number | |
60+
| ------ | ---------- | --------- | ---------- | ------ | ---- |
61+
| Bar34 | 10.3636 ms | 0.0000 ms | Bar | 34 | |
62+
| Bar3 | 10.4662 ms | 0.0000 ms | Bar | 3 | |
63+
| Foo12 | 10.1377 ms | 0.0000 ms | Foo | 12 | |
64+
| Foo1 | 10.2814 ms | 0.0000 ms | Foo | 1 | |
65+
66+
67+
### PlaceColumn
68+
TODO
69+
70+
## Custom columns
71+
72+
TODO
File renamed without changes.

docs/guide/Configs/Jobs.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Jobs
2+
3+
Basically, *job* describes how to run your benchmark. Practically, it's a set of characteristics which can be specified. You can set one or several jobs for your benchmarks.
4+
5+
## Characteristics
6+
7+
There are several categories of characteristics which you can specify. Let's consider each category in detail.
8+
9+
### Id
10+
It's a single string characteristics. It allows to name your job. This name will be used in logs and a part of a folder name with generated files for this job. `Id` doesn't affect benchmark results, but it can be useful for diagnostics. If you don't specify `Id`, random value will be chosed based on other characteristics
11+
12+
### Env
13+
`Env` specifies an environment of the job. You can specify the following characteristics:
14+
15+
* `Platform`: `x86` or `x64`
16+
* `Runtime`:
17+
* `Clr`: Full .NET Framework (available only on Windows)
18+
* `Core`: CoreCLR (x-plat)
19+
* `Mono`: Mono (x-plat)
20+
* `Jit`:
21+
* `LegacyJit` (available only for `Runtime.Clr`)
22+
* `RyuJit` (avaiable only for `Runtime.Clr` and `Runtime.Core`)
23+
* `Llvm` (avaiable only for `Runtime.Mono`)
24+
* `Affinity`: [Affinity](https://msdn.microsoft.com/library/system.diagnostics.process.processoraffinity.aspx) of a benchmark process
25+
* `GcMode`: settings of Garbage Collector
26+
* `Server`: `true` (Server mode) or `false` (Workstation mode)
27+
* `Concurrent`: `true` (Concurrent mode) or `false` (NonConcurrent mode)
28+
* `CpuGroups`: Specifies whether garbage collection supports multiple CPU groups
29+
* `Force`: Specifies whether the BenchmarkDotNet's benchmark runner forces full garbage collection after each benchmark invocation
30+
* `AllowVeryLargeObjects`: On 64-bit platforms, enables arrays that are greater than 2 gigabytes (GB) in total size
31+
32+
BenchmarkDotNet will use host process environment characteristics for non specified values.
33+
34+
### Run
35+
In this category, you can specifiy how to benchmark each method.
36+
37+
* `RunStrategy`:
38+
* `Throughput`: default strategy which allows to get good precision level
39+
* `ColdStart`: should be used only for measuring cold start of the application or testing purpose
40+
* `LaunchCount`: how many times we should launch process with target benchmark
41+
* `WarmupCount`: how many warmup iterations should be performed
42+
* `TargetCount`: how many target iterations should be performed
43+
* `IterationTime`: desired time of a single iteration
44+
* `InvocationCount`: count of invocation in a single iteration (if specified, `IterationTime` will be ignored)
45+
46+
Usually, you shouldn't specify such characteristics like `LaunchCount`, `WarmupCount`, `TargetCount`, or `IterationTime` because BenchmarkDotNet has a smart algorithm to choose these values automatically based on recieved measurements. You can specify it for testing purposes or when you are damn sure that you know perfect characteristics for your benchmark (when you set `TargetCount` = `20` you should unserstand why `20` is a good value for your case).
47+
48+
### Accuracy
49+
If you want to change the accuracy level, you should use the following characteristics instead of manual of values of `WarmupCount`, `TargetCount`, and so on.
50+
51+
* `MaxStdErrRelative`: Maximum relative standard error (`StandardError`/`Mean`) which you want to achive.
52+
* `MinIterationTime`: Minimum time of a single iteration. Unlike `Run.IterationTime`, this characteristic specify only the lower limit. In case of need, BenchmarkDotNet can increase this value.
53+
* `MinInvokeCount`: Minimum about of target method invocation. Default value if `4` but you can decrease this value for cases when single invocations takes a lot of time.
54+
* `EvaluateOverhead`: if you benchmark method takes nanoseconds, BenchmarkDotNet overhead can significantly affect measurements. If this characterics is enable, the overhead will be evaluated and substracted from the result measurements. Default value is `true`.
55+
* `RemoveOutliers`: sometimes you could have outliers in your measurements. Usually it's *unexpected* ourliers which arised because of other processes activities. If this characteristics is enable, all outliers will be removed from the result measurements. However, some of benchmarks have *expected* outliers. In these situation, you expect that some of invocation can produce ourliers measurements (e.g. in case of network acitivities, cache operations, and so on). If you want to see result statistics with these outliers, you should disable this characteristic. Default value is `true`.
56+
57+
### Infra
58+
Usually, you shouldn't specify any characteristics from this section, it can be used for advanced cases only.
59+
60+
* `Toolchain`: a toolchain which generate source code for target benchmark methods, build it, and execute it. BenchmarkDotNet has own toolchains for CoreCLR projects and classic projects (the last one is `RoslynToolchain`, you can find it in the [BenchmarkDotNet.Toolchains.Roslyn](https://www.nuget.org/packages/BenchmarkDotNet.Toolchains.Roslyn/) NuGet package). If you want, you can define own toolchain.
61+
* `Clock`: a clock which will be used for measurements. BenchmarkDotNet automatically choose the best available clock source, but you can specify own clock source.
62+
* `Engine`: a measurement engine which performs all the measurement magic. If you don't trust BenchmarkDotNet, you can define own engine and implement all the measurement stages manually.
63+
64+
## Usage
65+
66+
There are several ways to specify a job.
67+
68+
### Object style
69+
70+
You can create own jobs directly from the source code via a cusom config:
71+
72+
```cs
73+
[Config(typeof(Config))]
74+
public class MyBenchmarks
75+
{
76+
private class Config : ManualConfig
77+
{
78+
public Config()
79+
{
80+
Add(Job.Default.
81+
With(Platform.X64).
82+
With(Jit.RyuJit).
83+
With(Runtime.Core).
84+
WithLaunchCount(5).
85+
WithIterationTime(TimeInterval.Millisecond * 200).
86+
WithMaxStdErrRelative(0.01).
87+
WithId("MySuperJob")
88+
);
89+
}
90+
}
91+
// Benchmarks
92+
}
93+
```
94+
95+
Basically, it's a good idea to start with one of predefined jobs (e.g. `Job.Default` or `Job.Dry`) and modify it with help of `With*` methods.
96+
97+
### Attribute style
98+
99+
You can also add new jobs via attributes. Examples:
100+
101+
```cs
102+
[DryJob]
103+
[ClrJob, CoreJob, MonoJob]
104+
[LegacyJitX86Job, LegacyJitX64, RyuJitX64Job]
105+
[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 5, targetCount: 5, id: "FastAndDirtyJob")]
106+
public class MyBenchmarkClass
107+
```
108+
109+
#### Custom attributes
110+
111+
You can also create own custom attribute with your favorite set of jobs. Example:
112+
113+
```cs
114+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Assembly)]
115+
public class MySuperJobAttribute : Attribute, IConfigSource
116+
{
117+
protected MySuperJobAttribute()
118+
{
119+
var job = Job.Default.With(Runtime.Core).WithId("MySuperJob");
120+
Config = ManualConfig.CreateEmpty().With(job);
121+
}
122+
123+
public IConfig Config { get; }
124+
}
125+
126+
[MySuperJob]
127+
public class MyBenchmarks
128+
```
File renamed without changes.

0 commit comments

Comments
 (0)