BenchmarkDotNet v0.11.0
This is one of the biggest releases of BenchmarkDotNet ever. There are so many improvements. We have new documentation, many performance improvements, Job Mutators, better user experience, correct Ctrl+C handling, better generic benchmarks support, more scenarios for passing arguments to benchmarks, awesome support of console arguments, unicode support, LLVM support in MonoDisassembler, and many-many other improvements and bug fixes!
A big part of the features and bug fixes were implemented to meet the enterprise requirements of Microsoft to make it possible to port CoreCLR, CoreFX, and CoreFXLab to BenchmarkDotNet.
The release would not be possible without many contributions from amazing community members. This release is a combined effort. We build BenchmarkDotNet together to make benchmarking .NET code easy and available to everyone for free!
New documentation
We have many improvements in our documentation! The new docs include:
- DocFX under the hood
- Detailed changelogs which includes all commits, merged pull requests and resolved issues
- API references
- Code samples for main features:
we generate it automatically based on the
BenchmarkDotNet.Samples
project; it means that all samples can always be compiled (no more samples with outdated API) - Better UI
- Documentation versioning: now it's possible to look at the documentation for recent BenchmarkDotNet versions
Performance improvements
BenchmarkDotNet needs to be capable of running few thousands of CoreFX and CoreCLR benchmarks in an acceptable amount of time. The code itself was already optimized so we needed architectural and design changes to meet this requirement.
Generate one executable per runtime settings
To ensure that the side effects of one benchmark run does not affect another benchmark run BenchmarkDotNet generates, builds and runs every benchmark in a dedicated process. So far we were generating and building one executable per benchmark, now we generate and build one executable per runtime settings. So if you want to run ten thousands of benchmarks for .NET Core 2.1 we are going to generate and build single executable, not ten thousand. If you target multiple runtimes the build is going to be executed in parallel. Moreover, if one of the parallel builds fail it's going to be repeated in a sequential way.
Previously the time to generate and build 650 benchmarks from our Samples project was one hour. Now it's something around 13 seconds which means 276 X improvement for this particular scenario. You can see the changes here.
Don't execute long operations more than once per iteration
BenchmarkDotNet was designed to allow for very accurate and stable micro-benchmarking. One of the techniques that we use is manual loop unrolling. In practice, it meant that for every iteration we were executing the benchmark at least 16 times (the default UnrollFactor
value). It was of course not desired for the very time-consuming benchmarks.
So far this feature was always enabled by default and users would need to configure UnrollFactor=1
to disable it. Now BenchmarkDotNet is going to discover such scenario and don't perform manual loop unrolling for the very time-consuming benchmarks. BenchmarkDotNet uses Job.IterationTime
setting (the default is 0.5s) in the Pilot Experiment stage to determine how many times given benchmark should be executed per iteration.
Example:
public class Program
{
static void Main() => BenchmarkRunner.Run<Program>();
[Benchmark]
public void Sleep1s() => Thread.Sleep(TimeSpan.FromSeconds(1));
}
Time to run with the previous version: 374 seconds. With 0.11.0
it's 27 seconds which gives us almost 14 X improvement. A good example of benchmarks that are going to benefit from this change are computer game benchmarks and ML.NET benchmarks. You can see the changes here and here.
Exposing more configuration settings
The default settings were configured to work well with every scenario. Before running the benchmark, BenchmarkDotNet does not know anything about it. This is why it performs many warmup iterations before running the benchmarks.
When you author benchmarks and run them many times you can come up with custom settings that produce similar results but in a shorter manner of time. To allow you to do that we have exposed:
Job.MinIterationCount
(default value is 15)Job.MaxIterationCount
(default value is 100)Job.MinWarmupIterationCount
(default value is 6)Job.MaxWarmupIterationCount
(default value is 50)
User Experience
One of the biggest success factors of BenchmarkDotNet is a great user experience. The tool just works as expected and makes your life easy. We want to make it even better!
.NET Standard 2.0
We have ported BenchmarkDotNet to .NET Standard 2.0 and thanks to that we were able to not only simplify our code and build process but also merge BenchmarkDotNet.Core.dll
and BenchmarkDotNet.Toolchains.Roslyn.dll
into BenchmarkDotNet.dll
. We still support .NET 4.6 but we have dropped .NET Core 1.1 support. More information and full discussion can be found here.
Note: Our BenchmarkDotNet.Diagnostics.Windows
package which uses EventTrace
to implement ETW-based diagnosers was also ported to .NET Standard 2.0 and you can now use all the ETW diagnosers with .NET Core on Windows. We plan to add EventPipe support and make this page fully cross-platform and Unix compatible soon.
Using complex types as benchmark arguments
So far we have required the users to implement IParam
interface to make the custom complex types work as benchmark arguments/parameters. This has changed, now the users can use any complex types as arguments and it will just work (more).
public class Program
{
static void Main(string[] args) => BenchmarkRunner.Run<Program>();
public IEnumerable<object> Arguments()
{
yield return new Point2D(10, 200);
}
[Benchmark]
[ArgumentsSource(nameof(Arguments))]
public int WithArgument(Point2D point) => point.X + point.Y;
}
public class Point2D
{
public int X, Y;
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public override string ToString() => $"[{X},{Y}]";
}
Note: If you want to control what will be displayed in the summary you should override ToString
.
If IterationSetup is provided run benchmark once per iteration
When Stephen Toub says that something is buggy, it most probably is. BenchmarkDotNet performs multiple invocations of benchmark per every iteration. When we have exposed the [IterationSetup]
attribute many users were expecting that the IterationSetup
is going to be invoked before every benchmark execution.
It was invoked before every iteration, and iteration was more than one benchmark call if the user did not configure that explicitly. We have changed that and now if you provide an [IterationSetup]
method it is going to be executed before every iteration and iteration will invoke the benchmark just once.
public class Test
{
public static void Main() => BenchmarkRunner.Run<Test>();
[IterationSetup]
public void MySetup() => Console.WriteLine("MySetup");
[Benchmark]
public void MyBenchmark() => Console.WriteLine("MyBenchmark");
}
Before:
MySetup
MyBenchmark
MyBenchmark
MyBenchmark
MyBenchmark
(...)
After:
MySetup
MyBenchmark
MySetup
MyBenchmark
MySetup
MyBenchmark
(...)
Note: If you want to configure how many times benchmark should be invoked per iteration you can use the new [InvocationCountAttribute]
.
Job Mutators
Job
represents a set of settings to run the benchmarks. We run every benchmark for every job defined by the user. The problem was that so far many jobs were just added to the config instead of being merged with other jobs.
An example:
[ClrJob, CoreJob]
[GcServer(true)]
public class MyBenchmarkClass
Resulted in 3 jobs and 3 benchmark executions: ClrJob
, CoreJob
and GcServer(true)
for current runtime.
Now all Jobs and their corresponding attributes marked as mutators are going to be applied to other jobs, not just added to the config. So in this particular scenario, the benchmarks from MyBenchmarkClass
are going to be executed for .NET with Server GC enabled and .NET Core with Server GC enabled.
Mutators are great when you want to have a single, global config for all benchmarks and apply given settings only to selected types. You can find out more about mutators here.
Ctrl+C
When the user:
- presses
Ctrl+C
- presses
Ctrl+Break
- logs off
- closes console window
We are now going to close any existing ETW session created by BenchmarkDotNet and restore console colors (read more).
Handle OutOfMemoryException more gracefully
When our benchmark hits OutOfMemoryException
we print some nice explanation:
public class Program
{
static void Main(string[] args) => BenchmarkRunner.Run<Program>();
private List<object> list = new List<object>();
[Benchmark]
public void AntiPattern() => list.Add(new int[int.MaxValue / 2]);
}
OutOfMemoryException!
BenchmarkDotNet continues to run additional iterations until desired accuracy level is achieved. It's possible only if the benchmark method doesn't have any side-effects.
If your benchmark allocates memory and keeps it alive, you are creating a memory leak.
You should redesign your benchmark and remove the side-effects. You can use `OperationsPerInvoke`, `IterationSetup` and `IterationCleanup` to do that.
Trimming long strings
We used to display the values "as is" which was bad for long strings. Now the values are trimmed (more).
public class Long
{
[Params("text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7")]
public string Text;
[Benchmark]
public int HashCode() => Text.GetHashCode();
}
Method | Text |
---|---|
HashCode | text/(...)q=0.7 [86] |
More features
Generic benchmarks
BenchmarkDotNet supports generic benchmarks, all you need to do is to tell it which types should be used as generic arguments (read more).
[GenericTypeArguments(typeof(int))]
[GenericTypeArguments(typeof(char))]
public class IntroGenericTypeArguments<T>
{
[Benchmark] public T Create() => Activator.CreateInstance<T>();
}
Arguments
We now support more scenarios for passing arguments to benchmarks:
- passing arguments to asynchronous benchmarks (more)
- passing generic types
- passing arguments by reference
- passing jagged arrays (more)
- types with implicit cast operator to stack only types can be passed as given stack-only types to Benchmarks (more)
Example:
public class WithStringToReadOnlySpan
{
[Benchmark]
[Arguments("some string")]
public void AcceptsReadOnlySpan(ReadOnlySpan<char> notString)
}
Console Arguments
BenchmarkSwitcher
supports various console arguments (PR), to make it work you need to pass the args
to switcher:
class Program
{
static void Main(string[] args)
=> BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
}
Note: to get the most up-to-date info about supported console arguments run the benchmarks with --help
.
Filter
The --filter
or just -f
allows you to filter the benchmarks by their full name (namespace.typeName.methodName
) using glob patterns.
Examples:
- Run all benchmarks from System.Memory namespace:
-f System.Memory*
- Run all benchmarks:
-f *
- Run all benchmarks from ClassA and ClassB
-f *ClassA* *ClassB*
Note: If you would like to join all the results into a single summary, you need to use --join
.
Categories
You can also filter the benchmarks by categories:
--anyCategories
- runs all benchmarks that belong to any of the provided categories--allCategories
- runs all benchmarks that belong to all provided categories
Diagnosers
-m
,--memory
- enables MemoryDiagnoser and prints memory statistics-d
,--disassm
- enables DisassemblyDiagnoser and exports diassembly of benchmarked code
Runtimes
The --runtimes
or just -r
allows you to run the benchmarks for selected Runtimes. Available options are: Clr, Mono, Core and CoreRT.
Example: run the benchmarks for .NET and .NET Core:
dotnet run -c Release -- --runtimes clr core
More arguments
-j
,--job
(Default: Default) Dry/Short/Medium/Long or Default-e
,--exporters
GitHub/StackOverflow/RPlot/CSV/JSON/HTML/XML-i
,--inProcess
(Default: false) Run benchmarks in Process-a
,--artifacts
Valid path to accessible directory--outliers
(Default: OnlyUpper) None/OnlyUpper/OnlyLower/All--affinity
Affinity mask to set for the benchmark process--allStats
(Default: false) Displays all statistics (min, max & more)--attribute
Run all methods with given attribute (applied to class or method)
Other small improvements
- Unicode support:
now you can enable support of Unicode symbols like
μ
or±
with[EncodingAttribute.Unicode]
, an example: BenchmarkDotNet.Samples.IntroEncoding (see #735) - Better benchmark validation (see #693, #737)
- Improve .NET Framework version detection: now we support .NET Framework 4.7.2 (see #743)
- OutlierModes: now it's possible to control how to process outliers, an example BenchmarkDotNet.Samples.IntroOutliers (see #766)
- LLVM support in MonoDisassembler (see a7426e)
- Grand API renaming we try not to change public API, but sometimes it's necessary because we want to get a consistent and understandable API in v1.0.0. (see #787)
- Many-many small improvements and bug fixes
Milestone details
In the v0.11.0 scope, 65 issues were resolved and 34 pull requests were merged. This release includes 214 commits by 11 contributors.
Resolved issues (65)
- #136 Fastcheck for correctness of benchmark implementations
- #175 Add .NET Core support for Diagnostics package (assignee: @adamsitnik)
- #368 Memory leak and crash with [Setup] (assignee: @adamsitnik)
- #420 Make BenchmarkDotNet.Core runtime independent (assignee: @adamsitnik)
- #464 Iteration setup / cleanup should not be called for Idle() (assignee: @adamsitnik)
- #484 Broken HTTPS on site (assignee: @jongalloway)
- #487 Please consider using 'µs' instead of 'us'
- #551 List of structs and OutOfMemoryException
- #583 BenchmarkDotNet.Samples refactoring (assignee: @AndreyAkinshin)
- #586 IParam interface improvement (assignee: @adamsitnik)
- #638 Config with ryujit but it doesnt actually use ryujit? (assignee: @morgan-kn)
- #649 Searching docs leads to 404 page (assignee: @AndreyAkinshin)
- #665 Handle OutOfMemoryException more gracefully (assignee: @adamsitnik)
- #671 Why does BenchmarkRunner generate an isolated project per each benchmark method/job/params? (assignee: @adamsitnik)
- #698 Port to .NET Standard 2.0, drop .NET Core 1.1 support (assignee: @adamsitnik)
- #699 Generate one executable per runtime settings (assignee: @adamsitnik)
- #700 Improve local CoreCLR support (assignee: @adamsitnik)
- #701 Extend exported json file with FullName using xunit naming convention for integration purpose (assignee: @adamsitnik)
- #710 Use DocFX as a documentation generator (assignee: @AndreyAkinshin)
- #712 [Params] with arrays as params throws System.Reflection.TargetInvocationException (assignee: @adamsitnik)
- #713 How to specify the invocation/launch count per type when using Config for multiple runtimes? (assignee: @adamsitnik)
- #718 CoreRT support (assignee: @adamsitnik)
- #719 If fail to build in Parallel due to file access issues, try to build sequentially (assignee: @adamsitnik)
- #720 Add SummaryOrderPolicy.Declared
- #724 Allocated Memory results are not scaled with OperationPerInvoke (assignee: @adamsitnik)
- #726 Improve building guideline
- #729 Handle Ctrl+C/Break (assignee: @adamsitnik)
- #730 IterationSetup is not running before each benchmark invocation (assignee: @adamsitnik)
- #733 IOException when running in OneDrive Folder (assignee: @adamsitnik)
- #734 Handle missing Mono runtime more gracefully (assignee: @adamsitnik)
- #736 Reduce number of initial pilot ops to 1 or make it configurable (assignee: @adamsitnik)
- #738 Params string containing characters like quotes is not being escaped properly (assignee: @adamsitnik)
- #741 Give users nice warning when T in generic benchmark is not public
- #745 It should be possible to specify the generic arguments by using attributes
- #747 Better docs that explain what is target/launch/iteration/invocation count (assignee: @adamsitnik)
- #748 Very long string params/arguments should be trimmed (assignee: @adamsitnik)
- #749 WithId(…) is ignored unless it’s at the end of the fluent calls chain. (assignee: @adamsitnik)
- #763 Make MaxIterationCount configurable, keep current value as default (assignee: @adamsitnik)
- #765 Add .NET Core 2.2 support (assignee: @adamsitnik)
- #769 ArgumentsSource does not support Jagged Arrays (assignee: @adamsitnik)
- #774 Make it possible to use Span and other ByRefLike types with implicit cast operators as benchmark argument (assignee: @adamsitnik)
- #778 CS0104: 'Job' is an ambiguous reference between 'BenchmarkDotNet.Jobs.Job' and 'Nest.Job' (assignee: @adamsitnik)
- #779 StackOnlyTypesWithImplicitCastOperatorAreSupportedAsArguments doesn't work on .NET Core 2.0 (assignee: @adamsitnik)
- #787 Grand renaming
- #793 job=core for BenchmarkSwitcher (assignee: @adamsitnik)
- #794 Don't exclude allocation quantum side effects for .NET Core 2.0+ (assignee: @adamsitnik)
- #795 Broken BenchmarkSwitcher (assignee: @adamsitnik)
- #797 Allocated is not divided by OperationsPerInvoke (assignee: @adamsitnik)
- #802 AdaptiveHistogramBuilder.BuildWithFixedBinSize error when running benchmarks (assignee: @AndreyAkinshin)
- #804 What is the point of BuildScriptFilePath ? (assignee: @adamsitnik)
- #809 Make it possible to configure Min and Max Warmup Iteration Count (assignee: @adamsitnik)
- #810 handle new *Ansi events to make Inlining and TailCall Diagnosers work with .NET Core 2.2 (assignee: @adamsitnik)
- #811 Question/Suggestion is GcStats forcing a GC.Collect when it doesn't need to (assignee: @adamsitnik)
- #812 When will the next release be available on NuGet? (assignee: @adamsitnik)
- #813 Problems with MemoryDiagnoserTests on Mono and .NET Core 2.0 (assignee: @adamsitnik)
- #814 For type arguments we should display simple, not-trimmed name (assignee: @adamsitnik)
- #816 BenchmarkDotNet.Autogenerated.csproj is not working on .NET Core 2.1 (assignee: @adamsitnik)
- #817 Autogenerated project is missing dependencies (assignee: @adamsitnik)
- #818 Arguments should be passed to asynchronous benchmarks (assignee: @adamsitnik)
- #820 set DOTNET_MULTILEVEL_LOOKUP=0 when custom dotnet cli path is provided (assignee: @adamsitnik)
- #821 ArgumentsAttribute causes an error when used with a string containing quotes (assignee: @adamsitnik)
- #823 Allow to set multiple Setup/Cleanup targets without string concatenation (assignee: @adamsitnik)
- #827 An easy way to run a specific benchmark class via command line (assignee: @adamsitnik)
- #829 Error message for wrong command line filter (assignee: @adamsitnik)
- #832 Compilation Error CS0119 with ParamsSource (assignee: @adamsitnik)
Merged pull requests (34)
- #693 Jit runtime validation (by @morgan-kn)
- #717 V11 (by @adamsitnik)
- #725 Extend exported json file with FullName using xunit naming convention for integration purpose (by @adamsitnik)
- #727 Building guideline improvement (by @Rizzen)
- #728 BenchmarkReport Exporter (by @Rizzen)
- #735 Unicode support (by @Rizzen)
- #737 Return value validator (by @ltrzesniewski)
- #740 Follow up to #737 (by @ltrzesniewski)
- #742 Add .NET Framework 4.7.2 version constant (by @epeshk)
- #743 Improve .NET Framework version detection (by @epeshk)
- #744 BenchmarkClass Validator (by @Rizzen)
- #746 Addition to #743: use HasValue instead of casting (by @epeshk)
- #750 Addition to #744: Using single variable in test instead of two (by @Rizzen)
- #752 Update HowItWorks.md (by @Tornhoof)
- #753 Ability to pass multiple assemblies. (by @paulness)
- #754 generate IParams for users in smart way (by @adamsitnik)
- #757 Add SummaryOrderPolicy.Defined to return benchmarks as instantiated (by @afmorris)
- #758 Generic Benchmark Attribute (by @Rizzen)
- #760 don't execute long operations more than once per iteration (by @adamsitnik)
- #761 stop the ETW session on Ctrl+C + restore console colors ;), fixes #729 (by @adamsitnik)
- #764 if IterationSetup is provided, and InvocationCount and UnrollFactor are not, run benchmark once per iteration to avoid user confusion (by @adamsitnik)
- #766 Introduce OutlierMode (by @AndreyAkinshin)
- #771 have two main actions: with unroll and without, for no unroll icrease the step by 1 in pilot (not *2) (by @adamsitnik)
- #781 Initial DocFX support, fixes #710 (by @AndreyAkinshin)
- #783 BenchmarkDotNet.Samples refactoring, fixes #583 (by @AndreyAkinshin)
- #785 Improve filtering from console args (by @adamsitnik)
- #789 docs: add changelog (by @AndreyAkinshin)
- #790 add link to inprocesstoolchain (by @IanKemp)
- #796 docs: multiversion combobox (by @AndreyAkinshin)
- #799 Cpu info improvement (by @Rizzen)
- #800 job Mutators (by @adamsitnik)
- #824 Use 3rd party lib for console args parsing + support globs for filtering (by @adamsitnik)
- #830 Read StandardOutput in a smart way to avoid infinite loops (by @houseofcat)
- #833 initial release notes (by @adamsitnik)
Commits (214)
- defa7e port to .NET Standard 2.0 (by @adamsitnik)
- 626b03 keep .NET 4.6 in case somebody is on full framework, but not using .NET Standard (by @adamsitnik)
- ae4e22 merge BenchmarkDotNet.Toolchains.Roslyn into BenchmarkDotNet.Core (by @adamsitnik)
- 260704 update TraceEvent, port BenchmarkDotNet.Diagnostics.Windows to .NET Standard,... (by @adamsitnik)
- 324973 remove .NET Core 1.1 support, update tests (by @adamsitnik)
- 64d732 get it working (by @adamsitnik)
- 54b829 remove .NET Core 1.1 from the CI jobs (by @adamsitnik)
- ebf3d9 ups ;) (by @adamsitnik)
- 42d9ae Merge branch 'master' into annotations (by @adamsitnik)
- bc9975 cleanup (by @adamsitnik)
- 96dd4f merge BenchmarkDotNet and BenchmarkDotNet.Core (by @adamsitnik)
- 2dc21b group the benchmarks by runtime settings into partitions, #699 (by @adamsitnik)
- fbb283 generate one .cs with all types inside, #699 (by @adamsitnik)
- 334af2 build single exe, #699 (by @adamsitnik)
- b958a1 run selected type from all types in exe #699 (by @adamsitnik)
- 4f5714 polishing the code, #699 (by @adamsitnik)
- 0c26a4 reverting some magic .sln change which has most probably broken the Travis bu... (by @adamsitnik)
- c8a368 restore to a dedicated temp folder, rebuild only bare minumum, store everythi... (by @adamsitnik)
- bd04bd better debugging experience (#699): when building only 1 thing at a time, pri... (by @adamsitnik)
- fcf691 Improved local CoreCLR/CoreFX support, tested on all OSes #700, #702 (by @adamsitnik)
- 7fbd6c allow the users to define an extra nuget feed, don't force clear tag for loca... (by @adamsitnik)
- ad0fc8 Merge branch 'master' into v11 (by @adamsitnik)
- 8070e4 Merge remote-tracking branch 'origin/master' into v11 (by @adamsitnik)
- 0cccba post code review fixes, part of #175 (by @adamsitnik)
- 4acc15 new Runtime and Toolchain for CoreRT, #718 (by @adamsitnik)
- 657f05 don't use Expressions in Engine to avoid .NET Native compiler errors, #718 (by @adamsitnik)
- 8c93cf the .NET Native compiler complained about some dependencies from referenced p... (by @adamsitnik)
- c8ba5c If fail to build in Parallel due to file access issues, try to build sequenti... (by @adamsitnik)
- 7173f7 CoreRT does not support reflection yet, so we need to target .NET Core 2.1 to... (by @adamsitnik)
- 889270 trying to install Clang 3.9 for CoreRT tests purpose, #718 (by @adamsitnik)
- 967167 code review fixes, #718 (by @adamsitnik)
- 94863a Merge pull request #717 from dotnet/v11 (by @adamsitnik)
- 448752 Improved docs for Disassembly Diagnoser (by @adamsitnik)
- 600e5f add FromAssemblyAndTypes method to make it possible to auto-detect all benchm... (by @adamsitnik)
- 289292 Allocated Memory must be scaled with OperationPerInvoke, fixes #724 (by @adamsitnik)
- 1aa414 Actual Building Guide (by @Rizzen)
- cfd9fa Merge pull request #727 from Rizzen/master (by @adamsitnik)
- 7cfe09 Created Exporter and moved logic into (by @Rizzen)
- b9ff75 Merge pull request #728 from Rizzen/BenchmarkReportExporter (by @adamsitnik)
- adea8f support by ref Arguments (by @adamsitnik)
- 0ecd7e ignore auto-generated files cleanup errors, #733 (by @adamsitnik)
- cf5cd6 Handle missing Mono runtime more gracefully, fixes #734 (by @adamsitnik)
- 49495f Remove unused usings (by @AndreyAkinshin)
- 160516 Return value validator (#737), fixes #136 (by @ltrzesniewski)
- 396f0a Follow up to #737 (#740) (by @ltrzesniewski)
- 9dc4e8 Add .NET Framework 4.7.2 release number constant to GetCurrentVersionBasedOnW... (by @epeshk)
- 06ff2d Update link to manual with .NET Framework version constants (by @epeshk)
- f7d9ac Don't check Reference Assemblies folder existence for .NET Framework version ... (by @epeshk)
- ebc1f6 Remove hardcoded Program Files directory location (by @epeshk)
- 490304 Refactor framework version determining, extract logic from CsProjClassicNetTo... (by @epeshk)
- cbea7e Fix Program Files path on x86 systems (by @epeshk)
- 8071c8 ProgramFilesX86DirectoryPath field (by @epeshk)
- f1d726 Merge pull request #743 from epeshk/frameworkVersion (by @AndreyAkinshin)
- a36442 use HasValue instead of casting (by @epeshk)
- c7efcc Merge pull request #746 from epeshk/frameworkVersion (by @adamsitnik)
- 58f704 Give users nice warning when T in generic benchmark is not public, fixes #741 (by @Rizzen)
- 66f958 when dotnet build --no-restore fails, try to run with restore (by @adamsitnik)
- 52067c custom job Id should be preserved, fixes #749 (by @adamsitnik)
- 24ec6e Very long string params/arguments should be trimmed, fixes #748 (by @adamsitnik)
- b2e5b6 Params string containing characters like quotes is must be escaped properly, ... (by @adamsitnik)
- 10865c Better docs that explain what is target/launch/iteration/invocation count by ... (by @adamsitnik)
- 32ed86 Addition to #744: Using single variable instead of two (by @Rizzen)
- f2a71f Merge pull request #750 from Rizzen/744_addition (by @adamsitnik)
- eabfdd Update HowItWorks.md (by @Tornhoof)
- 8fc754 Merge pull request #752 from Tornhoof/patch-1 (by @adamsitnik)
- 2d79b6 Ability to pass multiple assemblies. (by @paulness)
- ba07b0 Merge pull request #753 from paulness/feature-allow-multiple-assemblies-to-be... (by @adamsitnik)
- d1b037 generate IParams for users in smart way (by @adamsitnik)
- 4665ec Merge pull request #754 from dotnet/noIParam (by @adamsitnik)
- 02c7c0 Generic Benchmark Attribute (#758), fixes #745 (by @Rizzen)
- 7caf28 Add SummaryOrderPolicy.Defined to return benchmarks as instantiated (#757), f... (by @afmorris)
- 449002 renamed Defined to Declared to keep consistency, renamed GenericBenchmark to ... (by @adamsitnik)
- 8855a2 Jit runtime validation (#693) (by @morgan-kn)
- 41614b stop the ETW session on Ctrl+C + restore console colors ;), fixes #729 (#761) (by @adamsitnik)
- b0c251 Make MaxIterationCount configurable, keep current value as default, fixes #763 (by @adamsitnik)
- 6f693e warn the users (once!) that if they run less than 15 iterations, the Multimod... (by @adamsitnik)
- a9664f don't execute long operations more than once per iteration (#760), fixes #736 (by @adamsitnik)
- 7e8448 if IterationSetup is provided, and InvocationCount and UnrollFactor are not, ... (by @adamsitnik)
- a40c75 explain the users why they did hit OOM, fixes #665, #368, #551 (by @adamsitnik)
- e66bb0 arrays can be arguments and params, fixes #712 (by @adamsitnik)
- 94b83e don't call IterationSetup and Cleanup for Idle, fixes #464 (by @adamsitnik)
- 90f9ca Add .NET Core 2.2 support, fixes #765 (by @adamsitnik)
- 132048 Better mValue formatting in MultimodalDistributionAnalyzer (by @AndreyAkinshin)
- 5f08c2 Merge pull request #764 from dotnet/iterationSetupRunOnce (by @AndreyAkinshin)
- 2b5dde Introduce OutlierMode (by @AndreyAkinshin)
- 226716 OutliersAnalyserTests (by @AndreyAkinshin)
- cabef0 support Jagged Arrays for ArgumentsSource, fixes #769 (by @adamsitnik)
- 808a9d support generic by ref arguments with an ugly hack due to reflection limitati... (by @adamsitnik)
- ea9f70 remove the ugly hack (by @adamsitnik)
- cb4291 make it possible to use arrays of types with no public parameterless ctor (li... (by @adamsitnik)
- 272e42 diassembly diagnoser: handle case where two different methods have same meta... (by @adamsitnik)
- ea16d1 update preview dependencies to 4.5.0 (by @adamsitnik)
- 97ddd6 Make it possible to use Span as benchmark argumen, fixes #774 (by @adamsitnik)
- 4863be more generic solution for #774 (by @adamsitnik)
- f63726 update build to use rc1 (to fix the build) (by @adamsitnik)
- a38c70 make it possible to pass array(s) of reference types as arguments (by @adamsitnik)
- 306adc use full Job type name to avoid naming conflicts, fixes #778 (by @adamsitnik)
- e92c5b use DOTNET_MULTILEVEL_LOOKUP and IgnoreCorLibraryDuplicatedTypes to fix the... (by @adamsitnik)
- 4e9844 Trimming the argument values makes them actually shorter #748 cc @ahsonkhan (by @adamsitnik)
- 846d80 Merge branch 'master' of https://github.com/dotnet/BenchmarkDotNet (by @adamsitnik)
- 3c3b47 have two main actions: with unroll and without, for no unroll icrease the ste... (by @adamsitnik)
- 56f02c use full names in the auto-generated code to avoid possible conflicts (I just... (by @adamsitnik)
- e75c44 Update documentations for WithOutlierMode (by @AndreyAkinshin)
- 1840ae Merge pull request #766 from dotnet/outliers (by @AndreyAkinshin)
- 5ae4bc Fixed BrandString support for Windows 10.0.17134 (by @AndreyAkinshin)
- 4d6dfe BrandString support for macOS Mojave (by @AndreyAkinshin)
- 426fbc Initial DocFX support, fixes #710 (by @AndreyAkinshin)
- fe00d7 Merge pull request #781 from dotnet/docfx (by @AndreyAkinshin)
- f0c06e Allow to pass string as ReadOnlySpan
only for .NET Core 2.1 where the i... (by @adamsitnik) - bbe273 make netcoreapp2.1 default for .NET Core 2.1 + expose few things which are re... (by @adamsitnik)
- bd22b3 BenchmarkDotNet.Samples refactoring, fixes #583 (by @AndreyAkinshin)
- 149e5e Merge pull request #783 from dotnet/docfx-samples (by @AndreyAkinshin)
- 237e36 Flat namespace for BenchmarkDotNet.Attributes (by @AndreyAkinshin)
- 24d2fe Remove obsolete namespaces in IntegrationTests (by @AndreyAkinshin)
- cb25a7 docs: Visual Studio-like style for code snippets (by @AndreyAkinshin)
- 914922 docs: add samples for baselines (by @AndreyAkinshin)
- 159e85 docs: fix year in license (by @AndreyAkinshin)
- 0b02d0 docs: add IntroEnvVars (by @AndreyAkinshin)
- 4b0f38 Unicode support (#735) (by @Rizzen)
- 971236 Unicode support: cleanup (by @AndreyAkinshin)
- 7c43da CommonExtensions cleanup (by @AndreyAkinshin)
- 04c0ad Fix link to rplot.png in README.md (by @AndreyAkinshin)
- b16b83 docs: samples for setup and cleanup (by @AndreyAkinshin)
- c05ac6 add link to inprocesstoolchain (#790) (by @IanKemp)
- 44ea0f docs: add changelog (#789) (by @AndreyAkinshin)
- 8a31aa docs: save changelog details for old versions in repo (by @AndreyAkinshin)
- edd0a3 docs: customizing-runtime.md (by @AndreyAkinshin)
- edf7f6 Improve filtering from console args (#785) (by @adamsitnik)
- d9e18d a type can have no namespace (by @adamsitnik)
- 4bbffe docs: update docfx version (by @AndreyAkinshin)
- 52e769 Don't exclude allocation quantum side effects for .NET Core 2.0+, fixes #794 (by @adamsitnik)
- 24f8da Cake targets for DocFX (by @AndreyAkinshin)
- db0724 docs: add api/index.md (by @AndreyAkinshin)
- 026c00 docs: statistics (by @AndreyAkinshin)
- ae5baf docs: misc fixes (by @AndreyAkinshin)
- fa5cf5 docs: multiversion combobox (by @AndreyAkinshin)
- a49cf9 docs: add full contributor list (by @AndreyAkinshin)
- 803686 always use FQDN to avoid any possible duplicates, #529 strikes back after a year (by @adamsitnik)
- 315530 make sure DisassemblyDiagnoser output is exported, fixes bug introduced in #785 (by @adamsitnik)
- 167476 docs: improved diagnosers.md (by @AndreyAkinshin)
- b7f9aa docs: improved choosing-run-strategy (by @AndreyAkinshin)
- 5da534 remove MultimodalDistributionAnalyzer hint introduced in #763 (by @adamsitnik)
- 376339 Merge pull request #796 from dotnet/docs-versions (by @adamsitnik)
- 57005f Extend exported json file with FullName using xunit naming convention for int... (by @adamsitnik)
- 9c0a2e docs: improved exporters.md (by @AndreyAkinshin)
- 22f553 docs: better sample generation (by @AndreyAkinshin)
- 734635 docs: improved columns.md (by @AndreyAkinshin)
- a82562 docs: improved configs.md (by @AndreyAkinshin)
- e7a458 docs: InProcess samples (by @AndreyAkinshin)
- 602562 docs: imrpovded order-providers.md (by @AndreyAkinshin)
- 8576c5 docs: fix the rest of WithoutDocs samples (by @AndreyAkinshin)
- 13b44e docs: rename changelog-generator to _changelog (by @AndreyAkinshin)
- 9a9648 docs: fix link to InProcessToolchain (by @AndreyAkinshin)
- 5716c1 escape tabs and enters in the exported benchmark id (to keep it in sync with ... (by @adamsitnik)
- 4be9bf MemoryDiagnoser handles IterationSetup and Cleanup since #606, removing old i... (by @adamsitnik)
- f92532 add --job=core to command line arguments, fixes #793 (by @adamsitnik)
- 1c656d update the docs with the change in IterationSetup behavior, #764 (by @adamsitnik)
- 6fd39b job Mutators (#800)fixes #713 (by @adamsitnik)
- 8954dc Rename: OrderProvider -> Orderer (#787) (by @AndreyAkinshin)
- 7b47c6 Rename: Benchmark -> BenchmarkCase (#787) (by @AndreyAkinshin)
- cc6f1b Rename: Target -> Descriptor (#787) (by @AndreyAkinshin)
- 17bb68 Rename: EnvMode -> EnvironmentMode (#787) (by @AndreyAkinshin)
- 73a6cc Rename: Infrastructure.EnvironmentVariables -> Environment.EnvironmentVariabl... (by @AndreyAkinshin)
- 6118f1 Huge IterationMode renaming (#787) (by @AndreyAkinshin)
- 035452 Handle super narrow distributions in AdaptiveHistogramBuilder, fixes #802 (by @AndreyAkinshin)
- b705b3 print Processor Affinity as a bitmask in the summary (by @adamsitnik)
- 0db126 fix MacOs build where the default affinity is 0 or we can't read it for some ... (by @adamsitnik)
- 5e6e33 make sure the characteristic names match the properties names + rename Target... (by @adamsitnik)
- f4cd0d Baseline improvements (#787) (by @AndreyAkinshin)
- 124a52 Fix tests (#787) (by @AndreyAkinshin)
- e8bf99 fix mac test, make sure IsMutator does not flow to applied job (by @adamsitnik)
- 95750c Make it possible to configure Min and Max Warmup Iteration Count, fixes #809 (by @adamsitnik)
- 99e753 handle new *Ansi events to make Inlining and TailCall Diagnosers work with .N... (by @adamsitnik)
- 62e75c docs: update articles/contributing/documentation (by @AndreyAkinshin)
- 41c5f9 Cake: update DocFX (2.36.2->2.37) (by @AndreyAkinshin)
- e4b37c Cake: update .NET Core SDK (2.1.300-rc1-008673->2.1.300) (by @AndreyAkinshin)
- ad1645 Cpu info improvement (#799) (by @Rizzen)
- 61e95e [Params] exported to json should be delimited by ", " #701 (by @adamsitnik)
- 4cd1df handle the types as arguments to match xunit naming convention for porting pu... (by @adamsitnik)
- ff6613 for type parameters we should display non-trimmed type name without namespace... (by @adamsitnik)
- 89f195 explain how we measure GC stats in the docs, fixes #811 (by @adamsitnik)
- c7731c Arguments should be passed to asynchronous benchmarks, fixes #818 (by @adamsitnik)
- 0f9c48 add info about Min/Max counts to docs (by @adamsitnik)
- 33e568 fix MemoryDiagnoserTests issues, fixes #813 (by @adamsitnik)
- 844e95 set DOTNET_MULTILEVEL_LOOKUP=0 to get customDotNetCli path working, fixes #820 (by @adamsitnik)
- 7e2d54 if iteration cleanup is provided, the benchmark should be executed once per i... (by @adamsitnik)
- 2132d0 allow to set summary style in fluent way (by @adamsitnik)
- dfea69 allow to set multuple targets for attributes without string concatenation, fi... (by @adamsitnik)
- 6267b2 Use 3rd party lib for console args parsing + support globs for filtering (#824) (by @adamsitnik)
- 9c269f make sure the generic type arguments are displayed in the summary, not `1 (by @adamsitnik)
- c7d0b9 don't duplicate the jobs when parsing config (by @adamsitnik)
- d7825e show generic type name in a joined summary (by @adamsitnik)
- 528c9c make sure the config parsing and job merging works as expected (by @adamsitnik)
- a7426e LLVM support in MonoDisassembler (by @AndreyAkinshin)
- c724e9 Fix typos (by @AndreyAkinshin)
- cdbb37 allow to filter benchmarks by simple type name, fixes #827 (by @adamsitnik)
- eac833 Read StandardOutput in a smart way to avoid infinite loops (#830), #828 (by @houseofcat)
- a298c2 Error message for wrong command line filter, fixes #829 (by @adamsitnik)
- a7ecda initial release notes (#833) (by @adamsitnik)
- 36bf7c Rename: General -> Actual (#787) (by @AndreyAkinshin)
- a1ec4b Add _changelog/details/v0.11.0.md (by @AndreyAkinshin)
- 558cae Improved docs for v0.11.0 (by @AndreyAkinshin)
- e45f69 docs: update main.js (by @AndreyAkinshin)
- 53e576 Update links to docs in README (by @AndreyAkinshin)
- 3a8990 update links in docs/index.md (by @AndreyAkinshin)
- 5ad710 Repair obsolete logo link (by @AndreyAkinshin)
- e38afb Cake: update DocFX (2.37->2.37.1) (by @AndreyAkinshin)
- 5b8f91 docs: add analytics scripts in template (by @AndreyAkinshin)
- 3ec8f7 docs: add redirects to v0.10.14 (by @AndreyAkinshin)
- a00bf6 docs: update how-it-works (by @AndreyAkinshin)
- 73980e docs: add redirect for index.htm (by @AndreyAkinshin)
- fad583 docs: update changelog for v0.11.0 (by @AndreyAkinshin)
- 74d552 Update list of NuGet packages in changelog/footer/v0.11.0 (by @AndreyAkinshin)
- 74084f Set library version: 0.11.0 (by @AndreyAkinshin)
Contributors (11)
- Adam Sitnik (@adamsitnik)
- Andrey Akinshin (@AndreyAkinshin)
- Evgeny Peshkov (@epeshk)
- Ian Kemp (@IanKemp)
- Irina Ananeva (@morgan-kn)
- Lucas Trzesniewski (@ltrzesniewski)
- Mark Tkachenko (@Rizzen)
- Paul Ness (@paulness)
- Stefan (@Tornhoof)
- Tony Morris (@afmorris)
- Tristan Hyams (@houseofcat)
Thank you very much!
Additional details
Date: July 23, 2018
Milestone: v0.11.0 (List of commits)
NuGet Packages: