diff --git a/LICENSE.md b/LICENSE.md
index 3bf1f0a225..d20c387e81 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
### The MIT License
-Copyright (c) 2013–2021 .NET Foundation and contributors
+Copyright (c) 2013–2023 .NET Foundation and contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
index d51eaab7f0..e92c4fa013 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ It's no harder than writing unit tests!
Under the hood, it performs a lot of [magic](#Automation) that guarantees [reliable and precise](#Reliability) results thanks to the [perfolizer](https://github.com/AndreyAkinshin/perfolizer) statistical engine.
BenchmarkDotNet protects you from popular benchmarking mistakes and warns you if something is wrong with your benchmark design or obtained measurements.
The results are presented in a [user-friendly](#Friendliness) form that highlights all the important facts about your experiment.
-The library is adopted by [13400+ projects](#who-uses-benchmarkdotnet) including .NET Runtime and supported by the [.NET Foundation](https://dotnetfoundation.org).
+The library is adopted by [13800+ projects](#who-uses-benchmarkdotnet) including .NET Runtime and supported by the [.NET Foundation](https://dotnetfoundation.org).
It's [easy](#Simplicity) to start writing benchmarks, check out an example
(copy-pastable version is [here](https://benchmarkdotnet.org/articles/guides/getting-started.html)):
@@ -231,7 +231,7 @@ If you don't customize the summary view,
## Who uses BenchmarkDotNet?
Everyone!
-BenchmarkDotNet is already adopted by more than [13400+](https://github.com/dotnet/BenchmarkDotNet/network/dependents?package_id=UGFja2FnZS0xNTY3MzExMzE%3D) projects including
+BenchmarkDotNet is already adopted by more than [13800+](https://github.com/dotnet/BenchmarkDotNet/network/dependents?package_id=UGFja2FnZS0xNTY3MzExMzE%3D) projects including
[dotnet/performance](https://github.com/dotnet/performance) (reference benchmarks for all .NET Runtimes),
[dotnet/runtime](https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=BenchmarkDotNet) (.NET runtime and libraries),
[Roslyn](https://github.com/dotnet/roslyn/search?q=BenchmarkDotNet&type=Issues&utf8=✓) (C# and Visual Basic compiler),
@@ -266,9 +266,9 @@ BenchmarkDotNet is already adopted by more than [13400+](https://github.com/dotn
[TensorFlow.NET](https://github.com/SciSharp/TensorFlow.NET/tree/master/src/TensorFlowNet.Benchmarks),
[Apache Thrift](https://github.com/apache/thrift/tree/master/lib/netstd/Benchmarks/Thrift.Benchmarks).
On GitHub, you can find
- 10700+ [issues](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=created&type=Issues&utf8=✓),
- 4700+ [commits](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=committer-date&type=Commits&utf8=✓), and
- 1,500,000+ [files](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=indexed&type=Code&utf8=✓)
+ 11400+ [issues](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=created&type=Issues&utf8=✓),
+ 4900+ [commits](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=committer-date&type=Commits&utf8=✓), and
+ 1,550,000+ [files](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=indexed&type=Code&utf8=✓)
that involve BenchmarkDotNet.
## Learn more about benchmarking
diff --git a/appveyor.yml b/appveyor.yml
index 8576caeca8..ec06524d19 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -3,7 +3,7 @@
#---------------------------------#
# version format
-version: 0.13.3.{build}
+version: 0.13.4.{build}
# branches to build
branches:
diff --git a/build/Program.cs b/build/Program.cs
index df59b52802..2094942ec4 100644
--- a/build/Program.cs
+++ b/build/Program.cs
@@ -280,10 +280,11 @@ public static class DocumentationHelper
"v0.12.1",
"v0.13.0",
"v0.13.1",
- "v0.13.2"
+ "v0.13.2",
+ "v0.13.3"
};
- public const string BdnNextVersion = "v0.13.3";
+ public const string BdnNextVersion = "v0.13.4";
public const string BdnFirstCommit = "6eda98ab1e83a0d185d09ff8b24c795711af8db1";
}
@@ -457,10 +458,6 @@ public override void Run(BuildContext context)
DocumentationHelper.BdnAllVersions[i - 1]);
} else if (context.Argument("LatestVersions", false))
{
- for (int i = DocumentationHelper.BdnAllVersions.Length - 2; i < DocumentationHelper.BdnAllVersions.Length; i++)
- context.DocfxChangelogDownload(
- DocumentationHelper.BdnAllVersions[i],
- DocumentationHelper.BdnAllVersions[i - 1]);
}
if (!context.Argument("StableVersions", false))
@@ -468,6 +465,11 @@ public override void Run(BuildContext context)
DocumentationHelper.BdnNextVersion,
DocumentationHelper.BdnAllVersions.Last(),
"HEAD");
+
+ for (int i = DocumentationHelper.BdnAllVersions.Length - 3; i < DocumentationHelper.BdnAllVersions.Length; i++)
+ context.DocfxChangelogDownload(
+ DocumentationHelper.BdnAllVersions[i],
+ DocumentationHelper.BdnAllVersions[i - 1]);
}
}
diff --git a/build/common.props b/build/common.props
index 8eb374e1c5..fb206917a1 100644
--- a/build/common.props
+++ b/build/common.props
@@ -38,7 +38,7 @@
0
13
- 3
+ 4
$(APPVEYOR_BUILD_NUMBER)
0
diff --git a/docs/_changelog/details/v0.13.1.md b/docs/_changelog/details/v0.13.1.md
index 05ca7aab6d..fd6f07b9f4 100644
--- a/docs/_changelog/details/v0.13.1.md
+++ b/docs/_changelog/details/v0.13.1.md
@@ -1,8 +1,8 @@
## Milestone details
In the [v0.13.1](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone:v0.13.1) scope,
-3 issues were resolved and 22 pull requests were merged.
-This release includes 36 commits by 10 contributors.
+3 issues were resolved and 23 pull requests were merged.
+This release includes 36 commits by 9 contributors.
## Resolved issues (3)
@@ -10,7 +10,7 @@ This release includes 36 commits by 10 contributors.
* [#1713](https://github.com/dotnet/BenchmarkDotNet/issues/1713) System.NotSupportedException: Unknown Acknowledgment: Acknowledgment when running in a github action (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#1714](https://github.com/dotnet/BenchmarkDotNet/issues/1714) AwaitingTasksShouldNotInterfereAllocationResults is flaky (assignee: [@adamsitnik](https://github.com/adamsitnik))
-## Merged pull requests (22)
+## Merged pull requests (23)
* [#1705](https://github.com/dotnet/BenchmarkDotNet/pull/1705) do not split surrogates in `ParameterInstance.ToDisplayText()` (by [@novak-as](https://github.com/novak-as))
* [#1710](https://github.com/dotnet/BenchmarkDotNet/pull/1710) Fix typo (by [@martincostello](https://github.com/martincostello))
@@ -20,6 +20,7 @@ This release includes 36 commits by 10 contributors.
* [#1725](https://github.com/dotnet/BenchmarkDotNet/pull/1725) Add ValidateExecutableReferencesMatchSelfContained (by [@kant2002](https://github.com/kant2002))
* [#1729](https://github.com/dotnet/BenchmarkDotNet/pull/1729) Naricc/validate executable references match self contained (by [@naricc](https://github.com/naricc))
* [#1735](https://github.com/dotnet/BenchmarkDotNet/pull/1735) Use Utf8 not just for writing to standard output, but also for reading from standard input (by [@adamsitnik](https://github.com/adamsitnik))
+* [#1739](https://github.com/dotnet/BenchmarkDotNet/pull/1739) Add support for returning unmanaged types from benchmarks (by [@kant2002](https://github.com/kant2002))
* [#1742](https://github.com/dotnet/BenchmarkDotNet/pull/1742) Fix WasmAssembliesToBundle item is empty error (by [@radekdoulik](https://github.com/radekdoulik))
* [#1743](https://github.com/dotnet/BenchmarkDotNet/pull/1743) Add linker description for wasm AOT (by [@radekdoulik](https://github.com/radekdoulik))
* [#1744](https://github.com/dotnet/BenchmarkDotNet/pull/1744) Make mono/wasm run on Windows (by [@radekdoulik](https://github.com/radekdoulik))
@@ -62,7 +63,7 @@ This release includes 36 commits by 10 contributors.
* [c3fb7b](https://github.com/dotnet/BenchmarkDotNet/commit/c3fb7b9724a62048d27ef5bcaec616117d68b934) Add support for returning unmanaged types from benchmarks (#1739) (by [@kant2002](https://github.com/kant2002))
* [6f453b](https://github.com/dotnet/BenchmarkDotNet/commit/6f453baafa4ef800e0377ebc463ffa82b2f76368) [wasm] Allow unsafe code (#1752) (by [@radekdoulik](https://github.com/radekdoulik))
* [c2cee2](https://github.com/dotnet/BenchmarkDotNet/commit/c2cee254b3a9aec3a6b73bc7fd21b7f2f70ca2ec) Fix the CI (by [@radekdoulik](https://github.com/radekdoulik))
-* [19cbef](https://github.com/dotnet/BenchmarkDotNet/commit/19cbef28cba94cd4a7da6266b839d4d3fe2f14db) Fix typo in docs (#1748) (by [@Jlobblet](https://github.com/Jlobblet))
+* [19cbef](https://github.com/dotnet/BenchmarkDotNet/commit/19cbef28cba94cd4a7da6266b839d4d3fe2f14db) Fix typo in docs (#1748) (by John Blundell)
* [1a94d4](https://github.com/dotnet/BenchmarkDotNet/commit/1a94d4dfa65f975f49d1bc92ced5c7a45bb994d4) [wasm] Add WasmMainJSPath in interpreter projects (#1757) (by [@radekdoulik](https://github.com/radekdoulik))
* [37ec19](https://github.com/dotnet/BenchmarkDotNet/commit/37ec19f6dba9ccee6a8f776aa3020ca189944f0c) Get rid of warning (#1760) (by [@radekdoulik](https://github.com/radekdoulik))
* [4bd433](https://github.com/dotnet/BenchmarkDotNet/commit/4bd433d85fff4fb6ba8c4f8df3e685ad669e2519) use benchmark process runtime, not host process runtime when deciding whether... (by [@adamsitnik](https://github.com/adamsitnik))
@@ -74,14 +75,13 @@ This release includes 36 commits by 10 contributors.
* [708be4](https://github.com/dotnet/BenchmarkDotNet/commit/708be495530a968ed767a20f4623f54231d1ab9b) Prepare v0.13.1 changelog (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
* [a93681](https://github.com/dotnet/BenchmarkDotNet/commit/a936815f2a58d9b728cfc5fe620bba17481c180c) Set library version: 0.13.1 (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
-## Contributors (10)
+## Contributors (9)
* Adam Sitnik ([@adamsitnik](https://github.com/adamsitnik))
* Andrey Akinshin ([@AndreyAkinshin](https://github.com/AndreyAkinshin))
* Andrii Kurdiumov ([@kant2002](https://github.com/kant2002))
-* Chris Granade ([@cgranade](https://github.com/cgranade))
-* Evgeny Grebenyuk ([@eugene-g](https://github.com/eugene-g))
-* John Blundell ([@Jlobblet](https://github.com/Jlobblet))
+* Cassandra Granade ([@cgranade](https://github.com/cgranade))
+* Evgenii Grebeniuk ([@eugene-g](https://github.com/eugene-g))
* Martin Costello ([@martincostello](https://github.com/martincostello))
* Nathan Ricci ([@naricc](https://github.com/naricc))
* Oleksandr Novak ([@novak-as](https://github.com/novak-as))
diff --git a/docs/_changelog/details/v0.13.2.md b/docs/_changelog/details/v0.13.2.md
index 302840d119..c982ce3ab3 100644
--- a/docs/_changelog/details/v0.13.2.md
+++ b/docs/_changelog/details/v0.13.2.md
@@ -1,22 +1,24 @@
## Milestone details
In the [v0.13.2](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone:v0.13.2) scope,
-44 issues were resolved and 124 pull requests were merged.
+50 issues were resolved and 124 pull requests were merged.
This release includes 147 commits by 34 contributors.
-## Resolved issues (44)
+## Resolved issues (50)
* [#299](https://github.com/dotnet/BenchmarkDotNet/issues/299) Add API to remove columns for baseline comparison (assignee: [@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* [#384](https://github.com/dotnet/BenchmarkDotNet/issues/384) Print Vector.Count as part of machine info (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#722](https://github.com/dotnet/BenchmarkDotNet/issues/722) Add scaled column for Allocated Memory
+* [#837](https://github.com/dotnet/BenchmarkDotNet/issues/837) Problems with default UnrollFactor in V0.11.0 (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#1177](https://github.com/dotnet/BenchmarkDotNet/issues/1177) Public types missing from reference assemblies don't work with ParamsSource
* [#1506](https://github.com/dotnet/BenchmarkDotNet/issues/1506) BenchmarkDotNet does not force to High Performance Mode during running (assignee: [@YegorStepanov](https://github.com/YegorStepanov))
* [#1603](https://github.com/dotnet/BenchmarkDotNet/issues/1603) Don't display Job and Toolchain column when running benchmarks for multiple runtimes
* [#1669](https://github.com/dotnet/BenchmarkDotNet/issues/1669) --buildTimeout does not seem to work (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#1680](https://github.com/dotnet/BenchmarkDotNet/issues/1680) Cannot override RD.xml for NativeAOT
-* [#1700](https://github.com/dotnet/BenchmarkDotNet/issues/1700) [Bug] Not unique exporter for exporter type
* [#1711](https://github.com/dotnet/BenchmarkDotNet/issues/1711) Add support for IBM Z architecture (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#1727](https://github.com/dotnet/BenchmarkDotNet/issues/1727) Unhelpful rounding in MemoryDiagnoser
* [#1753](https://github.com/dotnet/BenchmarkDotNet/issues/1753) "call: command not found" in .sh build script (assignee: [@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* [#1755](https://github.com/dotnet/BenchmarkDotNet/issues/1755) EventPipeProfiler: File names are very verbose
* [#1756](https://github.com/dotnet/BenchmarkDotNet/issues/1756) EventPipeProfile: speedscope.app cannot parse result file (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#1774](https://github.com/dotnet/BenchmarkDotNet/issues/1774) Ability to compare --corerun with --runtimes (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#1775](https://github.com/dotnet/BenchmarkDotNet/issues/1775) Please add an easy way to remove columns
@@ -27,6 +29,7 @@ This release includes 147 commits by 34 contributors.
* [#1809](https://github.com/dotnet/BenchmarkDotNet/issues/1809) Exception when using ParamsSource with (null) objects
* [#1812](https://github.com/dotnet/BenchmarkDotNet/issues/1812) Invalid codegen for Enumerable.Empty returned from ParamsSource
* [#1819](https://github.com/dotnet/BenchmarkDotNet/issues/1819) How to change exporter output path?
+* [#1836](https://github.com/dotnet/BenchmarkDotNet/issues/1836) [Bug] `System.InvalidOperationException: There is an error in XML document (0, 0).`
* [#1857](https://github.com/dotnet/BenchmarkDotNet/issues/1857) Github actions ubuntu-latest "Unable to load shared library 'advapi32.dll' or one of its dependencies" when profiling dotnet 5
* [#1864](https://github.com/dotnet/BenchmarkDotNet/issues/1864) Is there a way to join summaries as if the benchmarks were run separately? (assignee: [@AndreyAkinshin](https://github.com/AndreyAkinshin))
* [#1871](https://github.com/dotnet/BenchmarkDotNet/issues/1871) Detect ReSharper's Dynamic Program Analysis (assignee: [@adamsitnik](https://github.com/adamsitnik))
@@ -38,7 +41,10 @@ This release includes 147 commits by 34 contributors.
* [#1934](https://github.com/dotnet/BenchmarkDotNet/issues/1934) Ensure WorkloadActionUnroll and similar are optimized if possible
* [#1937](https://github.com/dotnet/BenchmarkDotNet/issues/1937) PR builds should not be published to BDN nightly feed (assignee: [@mawosoft](https://github.com/mawosoft))
* [#1943](https://github.com/dotnet/BenchmarkDotNet/issues/1943) GitHub Actions Windows CI leg failing due to lack of native tools (assignee: [@adamsitnik](https://github.com/adamsitnik))
+* [#1948](https://github.com/dotnet/BenchmarkDotNet/issues/1948) questions to help with future PRs
* [#1957](https://github.com/dotnet/BenchmarkDotNet/issues/1957) Broken pipe (assignee: [@adamsitnik](https://github.com/adamsitnik))
+* [#1977](https://github.com/dotnet/BenchmarkDotNet/issues/1977) More Data for JSON and XML Export
+* [#1989](https://github.com/dotnet/BenchmarkDotNet/issues/1989) Way to summarize all the params results (assignee: [@YegorStepanov](https://github.com/YegorStepanov))
* [#1992](https://github.com/dotnet/BenchmarkDotNet/issues/1992) API Docs on website empty (assignee: [@AndreyAkinshin](https://github.com/AndreyAkinshin))
* [#2000](https://github.com/dotnet/BenchmarkDotNet/issues/2000) DisassemblyDiagnoser broken on Linux (assignee: [@adamsitnik](https://github.com/adamsitnik))
* [#2009](https://github.com/dotnet/BenchmarkDotNet/issues/2009) Cleanup the dependencies (assignee: [@martincostello](https://github.com/martincostello))
diff --git a/docs/_changelog/details/v0.13.3.md b/docs/_changelog/details/v0.13.3.md
index 4ebe59754c..520692806a 100644
--- a/docs/_changelog/details/v0.13.3.md
+++ b/docs/_changelog/details/v0.13.3.md
@@ -2,7 +2,7 @@
In the [v0.13.3](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone:v0.13.3) scope,
29 issues were resolved and 72 pull requests were merged.
-This release includes 85 commits by 22 contributors.
+This release includes 87 commits by 22 contributors.
## Resolved issues (29)
@@ -111,7 +111,7 @@ This release includes 85 commits by 22 contributors.
* [#2234](https://github.com/dotnet/BenchmarkDotNet/pull/2234) Disassembler realiability fixes (by [@adamsitnik](https://github.com/adamsitnik))
* [#2235](https://github.com/dotnet/BenchmarkDotNet/pull/2235) tests can't assume x64 hardware (by [@adamsitnik](https://github.com/adamsitnik))
-## Commits (85)
+## Commits (87)
* [33b288](https://github.com/dotnet/BenchmarkDotNet/commit/33b288ff2918d31c461f0de64908f99e24a4b45e) Use latest AzDO macOS pool (#2085) (by [@adamsitnik](https://github.com/adamsitnik))
* [83750b](https://github.com/dotnet/BenchmarkDotNet/commit/83750baceb71cb0c81a01145a5872b63bc7db858) Postrelease v0.13.2 update (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
@@ -198,6 +198,8 @@ This release includes 85 commits by 22 contributors.
* [82f03f](https://github.com/dotnet/BenchmarkDotNet/commit/82f03f4d4222dfcf4e19e1f32a47867342a680d1) Add support for .NET SDK that uses Mono instead CLR as a default VM (#2230) (by [@adamsitnik](https://github.com/adamsitnik))
* [968448](https://github.com/dotnet/BenchmarkDotNet/commit/96844853b8c15eeed65ef8349aa9dbe47fb05248) Disassembler realiability fixes (#2234) (by [@adamsitnik](https://github.com/adamsitnik))
* [a098bc](https://github.com/dotnet/BenchmarkDotNet/commit/a098bc1761c9157dbca5bd10ef6d08840620136e) tests can't assume x64 hardware (#2235) (by [@adamsitnik](https://github.com/adamsitnik))
+* [2665ac](https://github.com/dotnet/BenchmarkDotNet/commit/2665ac7c38f3edecbd7f593f25941eb613cbd779) Prepare v0.13.3 changelog (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* [0714f5](https://github.com/dotnet/BenchmarkDotNet/commit/0714f5f4a97bc74ff0ac5860525527c8e8825205) Set library version: 0.13.3 (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
## Contributors (22)
diff --git a/docs/_changelog/details/v0.13.4.md b/docs/_changelog/details/v0.13.4.md
new file mode 100644
index 0000000000..b26a46c0cd
--- /dev/null
+++ b/docs/_changelog/details/v0.13.4.md
@@ -0,0 +1,37 @@
+## Milestone details
+
+In the [v0.13.4](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone:v0.13.4) scope,
+1 issues were resolved and 4 pull requests were merged.
+This release includes 7 commits by 5 contributors.
+
+## Resolved issues (1)
+
+* [#2237](https://github.com/dotnet/BenchmarkDotNet/issues/2237) Version 0.13.3 breaks LINQPad (and any non-Console application)
+
+## Merged pull requests (4)
+
+* [#2206](https://github.com/dotnet/BenchmarkDotNet/pull/2206) Add single quote when use pattern with filters (by [@erlangxk](https://github.com/erlangxk))
+* [#2218](https://github.com/dotnet/BenchmarkDotNet/pull/2218) Improve getting started guide (by [@reflectronic](https://github.com/reflectronic))
+* [#2238](https://github.com/dotnet/BenchmarkDotNet/pull/2238) Fix IOException when Console window unavailable (#2237) (by [@albahari](https://github.com/albahari))
+* [#2243](https://github.com/dotnet/BenchmarkDotNet/pull/2243) JitStatsDiagnoser (by [@adamsitnik](https://github.com/adamsitnik))
+
+## Commits (7)
+
+* [dc7734](https://github.com/dotnet/BenchmarkDotNet/commit/dc7734d3eba06880428c0e16d287c9ca837a9d40) Postrelease v0.13.3 update (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* [e04e2d](https://github.com/dotnet/BenchmarkDotNet/commit/e04e2d7d0cc4fefb954f8a8bd90b8f82100802f9) Fix IOException when Console window unavailable (#2237) (#2238) (by [@albahari](https://github.com/albahari))
+* [7694d0](https://github.com/dotnet/BenchmarkDotNet/commit/7694d0e79b7446373f893ff532b801a519f1b700) Update copyright year (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* [5e8a31](https://github.com/dotnet/BenchmarkDotNet/commit/5e8a318d2243701d0141d74a6c89307149486156) Revert comments in DocFxChangelogDownloadTask (by [@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* [ea0eb2](https://github.com/dotnet/BenchmarkDotNet/commit/ea0eb2fe403cab9c1daa0e5aa6e42ab038100418) Add single quote when use pattern with filters (#2206) (by [@erlangxk](https://github.com/erlangxk))
+* [0cf185](https://github.com/dotnet/BenchmarkDotNet/commit/0cf185020583a5c5c987d064d09426edc4399a5b) Improve getting started guide (#2218) (by [@reflectronic](https://github.com/reflectronic))
+* [12bf22](https://github.com/dotnet/BenchmarkDotNet/commit/12bf220e11fddc8e65b066eb1f300b63bfde7e9b) JitStatsDiagnoser (#2243) (by [@adamsitnik](https://github.com/adamsitnik))
+
+## Contributors (5)
+
+* Adam Sitnik ([@adamsitnik](https://github.com/adamsitnik))
+* albahari ([@albahari](https://github.com/albahari))
+* Andrey Akinshin ([@AndreyAkinshin](https://github.com/AndreyAkinshin))
+* erlangxk ([@erlangxk](https://github.com/erlangxk))
+* John Tur ([@reflectronic](https://github.com/reflectronic))
+
+Thank you very much!
+
diff --git a/docs/_changelog/footer/v0.13.3.md b/docs/_changelog/footer/v0.13.3.md
index ee7f61b702..f0fa6dff23 100644
--- a/docs/_changelog/footer/v0.13.3.md
+++ b/docs/_changelog/footer/v0.13.3.md
@@ -1,4 +1,4 @@
-_Date: TBA_
+_Date: December 26, 2022_
_Milestone: [v0.13.3](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone%3Av0.13.3)_
([List of commits](https://github.com/dotnet/BenchmarkDotNet/compare/v0.13.2...v0.13.3))
diff --git a/docs/_changelog/footer/v0.13.4.md b/docs/_changelog/footer/v0.13.4.md
new file mode 100644
index 0000000000..c98547637c
--- /dev/null
+++ b/docs/_changelog/footer/v0.13.4.md
@@ -0,0 +1,10 @@
+_Date: TBA_
+
+_Milestone: [v0.13.4](https://github.com/dotnet/BenchmarkDotNet/issues?q=milestone%3Av0.13.4)_
+([List of commits](https://github.com/dotnet/BenchmarkDotNet/compare/v0.13.3...v0.13.4))
+
+_NuGet Packages:_
+* https://www.nuget.org/packages/BenchmarkDotNet/0.13.4
+* https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/0.13.4
+* https://www.nuget.org/packages/BenchmarkDotNet.Annotations/0.13.4
+* https://www.nuget.org/packages/BenchmarkDotNet.Templates/0.13.4
\ No newline at end of file
diff --git a/docs/_changelog/full.md b/docs/_changelog/full.md
index d4d82c9b62..06f7b67eeb 100644
--- a/docs/_changelog/full.md
+++ b/docs/_changelog/full.md
@@ -4,6 +4,7 @@ uid: changelog.full
# Full ChangeLog
+[!include[v0.13.4](v0.13.4.md)]
[!include[v0.13.3](v0.13.3.md)]
[!include[v0.13.2](v0.13.2.md)]
[!include[v0.13.1](v0.13.1.md)]
diff --git a/docs/_changelog/header/v0.13.4.md b/docs/_changelog/header/v0.13.4.md
new file mode 100644
index 0000000000..3ae8407ee4
--- /dev/null
+++ b/docs/_changelog/header/v0.13.4.md
@@ -0,0 +1,26 @@
+## Highlights
+
+* Fixed LINQPad support
+ [#2237](https://github.com/dotnet/BenchmarkDotNet/issues/2237)
+ [#2238](https://github.com/dotnet/BenchmarkDotNet/pull/2238)
+* New `JitStatsDiagnoser`
+ [#2243](https://github.com/dotnet/BenchmarkDotNet/pull/2243)
+* Minor documentation improvements
+ [#2206](https://github.com/dotnet/BenchmarkDotNet/pull/2206)
+ [#2218](https://github.com/dotnet/BenchmarkDotNet/pull/2218)
+
+## JitStatsDiagnoser
+
+This new diagnoser introduced in ([#2243](https://github.com/dotnet/BenchmarkDotNet/pull/2243)) allows getting advanced JIT statistics.
+
+Sample usage:
+
+```cmd
+dotnet run -c Release -f net7.0 --filter *IntroBasic.Sleep --profiler jit
+```
+
+Result:
+
+| Method | Mean | Error | StdDev | Methods JITted | Methods Tiered | JIT allocated memory |
+|------- |---------:|---------:|---------:|---------------:|---------------:|---------------------:|
+| Sleep | 15.53 ms | 0.034 ms | 0.032 ms | 1,102 | 15 | 221,736 B |
\ No newline at end of file
diff --git a/docs/_changelog/index.md b/docs/_changelog/index.md
index e52aaae667..9495dc9da6 100644
--- a/docs/_changelog/index.md
+++ b/docs/_changelog/index.md
@@ -4,6 +4,7 @@ uid: changelog
# ChangeLog
+* @changelog.v0.13.4
* @changelog.v0.13.3
* @changelog.v0.13.2
* @changelog.v0.13.1
diff --git a/docs/articles/guides/console-args.md b/docs/articles/guides/console-args.md
index 6540ebab6a..951a789fa9 100644
--- a/docs/articles/guides/console-args.md
+++ b/docs/articles/guides/console-args.md
@@ -23,11 +23,11 @@ The `--filter` or just `-f` allows you to filter the benchmarks by their full na
Examples:
-1. Run all benchmarks from System.Memory namespace: `-f System.Memory*`
-2. Run all benchmarks: `-f *`
-3. Run all benchmarks from ClassA and ClassB `-f *ClassA* *ClassB*`
+1. Run all benchmarks from System.Memory namespace: `-f 'System.Memory*'`
+2. Run all benchmarks: `-f '*'`
+3. 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 put `--join`. For example: `-f *ClassA* *ClassB* --join`
+**Note**: If you would like to **join** all the results into a **single summary**, you need to put `--join`. For example: `-f '*ClassA*' '*ClassB*' --join`
## List of benchmarks
diff --git a/docs/articles/guides/getting-started.md b/docs/articles/guides/getting-started.md
index 70e5f592a0..5b744192ad 100644
--- a/docs/articles/guides/getting-started.md
+++ b/docs/articles/guides/getting-started.md
@@ -1,16 +1,14 @@
# Getting started
-
To get started with BenchmarkDotNet, please follow these steps.
## Step 1. Create a project
Create a new console application.
## Step 2. Installation
-
Install BenchmarkDotNet via the NuGet package: [BenchmarkDotNet](https://www.nuget.org/packages/BenchmarkDotNet/)
-```
-PM> Install-Package BenchmarkDotNet
+```cmd
+> dotnet add package BenchmarkDotNet
```
Read more about BenchmarkDotNet NuGet packages: @docs.nuget
@@ -58,39 +56,50 @@ namespace MyBenchmarks
}
```
-The `BenchmarkRunner.Run()` call runs your benchmarks and print results to console output.
+The `BenchmarkRunner.Run()` call runs your benchmarks and prints results to the console.
-## Step 4. View results
+## Step 4. Run benchmarks
+Start your console application to run the benchmarks. The application must be built in the Release configuration.
+
+```cmd
+> dotnet run -c Release
+```
+
+## Step 5. View results
View the results. Here is an example of output from the above benchmark:
```
-BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17134.472 (1803/April2018Update/Redstone4)
-Intel Core i7-2630QM CPU 2.00GHz (Sandy Bridge), 1 CPU, 8 logical and 4 physical cores
-Frequency=1948699 Hz, Resolution=513.1629 ns, Timer=TSC
-.NET Core SDK=2.1.502
- [Host] : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT
- DefaultJob : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT
-
-
-| Method | Mean | Error | StdDev |
-|------- |----------:|----------:|----------:|
-| Sha256 | 100.90 us | 0.5070 us | 0.4494 us |
-| Md5 | 37.66 us | 0.1290 us | 0.1207 us |
+BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2251)
+Intel Core i7-4770HQ CPU 2.20GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
+.NET SDK=7.0.100
+ [Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+ DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+
+
+| Method | Mean | Error | StdDev |
+|------- |---------:|---------:|---------:|
+| Sha256 | 51.57 us | 0.311 us | 0.291 us |
+| Md5 | 21.91 us | 0.138 us | 0.129 us |
```
+## Step 6. Analyze results
+BenchmarkDotNet will automatically create basic reports in the `.\BenchmarkDotNet.Artifacts\results` folder that can be shared and analyzed.
-## Step 5. Analyze results
+To help analyze performance in further depth, you can configure your benchmark to collect and output more detailed information. Benchmark configuration can be conveniently changed by adding attributes to the class containing your benchmarks. For example:
-Analyze it. In your bin directory, you can find a lot of useful files with detailed information. For example:
+* [Diagnosers](../configs/diagnosers.md)
+ * GC allocations: `[MemoryDiagnoser]`
+ * Code size and disassembly: `[DisassemblyDiagnoser]`
+ * Threading statistics: `[ThreadingDiagnoser]`
+* [Exporters](../configs/exporters.md)
+ * CSV reports with raw data: `[CsvMeasurementsExporter]`
+ * JSON reports with raw data: `[JsonExporter]`
+ * Plots (if you have installed R): `[RPlotExporter]`
-* Csv reports with raw data: `Md5VsSha256-report.csv`, `Md5VsSha256-runs.csv`
-* Markdown reports: `Md5VsSha256-report-default.md`, `Md5VsSha256-report-stackoverflow.md`, `Md5VsSha256-report-github.md`
- * Plain report and log: `Md5VsSha256-report.txt`, `Md5VsSha256.log`
- * Plots (if you have installed R): `Md5VsSha256-barplot.png`, `Md5VsSha256-boxplot.png`, and so on.
+For more information, see [Configs](../configs/configs.md).
## Next steps
-
-BenchmarkDotNet provides a lot of features which help to high-quality performance research.
-If you want to know more about BenchmarkDotNet features, checkout the [Overview](../overview.md) page.
-If you want have any questions, checkout the [FAQ](../faq.md) page.
-If you didn't find answer for your question on this page, [ask it on gitter](https://gitter.im/dotnet/BenchmarkDotNet) or [create an issue](https://github.com/dotnet/BenchmarkDotNet/issues).
+BenchmarkDotNet provides features which aid high-quality performance research.
+If you want to know more about BenchmarkDotNet features, check out the [Overview](../overview.md) page.
+If you have any questions, check out the [FAQ](../faq.md) page.
+If you didn't find an answer for your question on this page, [ask it on Gitter](https://gitter.im/dotnet/BenchmarkDotNet) or [create an issue on GitHub](https://github.com/dotnet/BenchmarkDotNet/issues).
diff --git a/docs/articles/guides/how-to-run.md b/docs/articles/guides/how-to-run.md
index cb585753ee..073cb0c078 100644
--- a/docs/articles/guides/how-to-run.md
+++ b/docs/articles/guides/how-to-run.md
@@ -31,25 +31,4 @@ Also you can use the config command style to specify some config from command li
dotnet run -c Release -- --job short --runtimes net472 net7.0 --filter *BenchmarkClass1*
```
-The most important thing about `BenchmarkSwitcher` is that you need to pass the `args` from `Main` to the `Run` method. If you don't, it won't parse the arguments.
-
-
-## Url
-
-You can also run a benchmark directly from the internet:
-
-```cs
-string url = "";
-var summary = BenchmarkRunner.RunUrl(url);
-```
-
-**Note:** it works only for Full .NET Framework. It's not recommended to use this approach.
-
-## Source
-
-```cs
-string benchmarkSource = "public class MyBenchmarkClass { ...";
-var summary = BenchmarkRunner.RunSource(benchmarkSource);
-```
-
-**Note:** it works only for Full .NET Framework. It's not recommended to use this approach.
+The most important thing about `BenchmarkSwitcher` is that you need to pass the `args` from `Main` to the `Run` method. If you don't, it won't parse the arguments.
\ No newline at end of file
diff --git a/docs/articles/overview.md b/docs/articles/overview.md
index 4e6f2c3d9c..e777049ee1 100644
--- a/docs/articles/overview.md
+++ b/docs/articles/overview.md
@@ -15,7 +15,7 @@ Create new console application and install the [BenchmarkDotNet](https://www.nug
* *Languages:* C#, F#, VB
## Design a benchmark
-Create a new console application, write a class with methods that you want to measure and mark them with the `Benchmark` attribute. In the following example, we
+Create a new console application, write a class with methods that you want to measure, and mark them with the `Benchmark` attribute. In the following example, we
compare the [MD5](https://en.wikipedia.org/wiki/MD5) and [SHA256](https://en.wikipedia.org/wiki/SHA-2) cryptographic hash functions:
```cs
@@ -57,71 +57,71 @@ namespace MyBenchmarks
}
```
-The `BenchmarkRunner.Run()` call runs your benchmarks and print results to console output.
+The `BenchmarkRunner.Run()` call runs your benchmarks and prints results to the console.
-Notice, that you should use only the `Release` configuration for your benchmarks.
-Otherwise, the results will not correspond to reality.
-If you forgot to change the configuration, BenchmarkDotNet will print a warning.
+Note that BenchmarkDotNet will only run benchmarks if the application is built in the Release configuration.
+This is to prevent unoptimized code from being benchmarked.
+BenchmarkDotNet will issue an error if you forget to change the configuration.
## Benchmark results
```
-BenchmarkDotNet=v0.11.3, OS=Windows 10.0.17134.472 (1803/April2018Update/Redstone4)
-Intel Core i7-2630QM CPU 2.00GHz (Sandy Bridge), 1 CPU, 8 logical and 4 physical cores
-Frequency=1948699 Hz, Resolution=513.1629 ns, Timer=TSC
-.NET Core SDK=2.1.502
- [Host] : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT
- DefaultJob : .NET Core 2.1.6 (CoreCLR 4.6.27019.06, CoreFX 4.6.27019.05), 64bit RyuJIT
-
-
-| Method | Mean | Error | StdDev |
-|------- |----------:|----------:|----------:|
-| Sha256 | 100.90 us | 0.5070 us | 0.4494 us |
-| Md5 | 37.66 us | 0.1290 us | 0.1207 us |
+BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2251)
+Intel Core i7-4770HQ CPU 2.20GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
+.NET SDK=7.0.100
+ [Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+ DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+
+
+| Method | Mean | Error | StdDev |
+|------- |---------:|---------:|---------:|
+| Sha256 | 51.57 us | 0.311 us | 0.291 us |
+| Md5 | 21.91 us | 0.138 us | 0.129 us |
```
## Jobs
-You can check several environments at once. For example, you can compare performance of Full .NET Framework, .NET Core, Mono and NativeAOT. Just add the `ClrJob`, `MonoJob`, `CoreJob`, attributes before the class declaration (it requires .NET SDK and Mono to be installed and added to $PATH):
+BenchmarkDotNet can benchmark your code in several environments at once. For example, to compare your benchmark's performance in .NET Framework, .NET Core, Mono and NativeAOT, you can add `SimpleJob` attributes to the benchmark class:
```cs
-[ClrJob, MonoJob, CoreJob]
+[SimpleJob(RuntimeMoniker.Net481)]
+[SimpleJob(RuntimeMoniker.Net70)]
+[SimpleJob(RuntimeMoniker.NativeAot70)]
+[SimpleJob(RuntimeMoniker.Mono)]
public class Md5VsSha256
```
Example of the result:
-```ini
-BenchmarkDotNet=v0.11.0, OS=Windows 10.0.16299.309 (1709/FallCreatorsUpdate/Redstone3)
-Intel Xeon CPU E5-1650 v4 3.60GHz, 1 CPU, 12 logical and 6 physical cores
-Frequency=3507504 Hz, Resolution=285.1030 ns, Timer=TSC
-.NET Core SDK=2.1.300-preview1-008174
- [Host] : .NET Core 2.1.0-preview1-26216-03 (CoreCLR 4.6.26216.04, CoreFX 4.6.26216.02), 64bit RyuJIT
- Job-YRHGTP : .NET Framework 4.7.1 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.2633.0
- Core : .NET Core 2.1.0-preview1-26216-03 (CoreCLR 4.6.26216.04, CoreFX 4.6.26216.02), 64bit RyuJIT
- CoreRT : .NET CoreRT 1.0.26414.01, 64bit AOT
- Mono : Mono 5.10.0 (Visual Studio), 64bit
-
-| Method | Runtime | Mean | Error | StdDev |
-|------- |-------- |-----------:|----------:|----------:|
-| Sha256 | Clr | 75.780 us | 1.0445 us | 0.9771 us |
-| Sha256 | Core | 41.134 us | 0.2185 us | 0.1937 us |
-| Sha256 | CoreRT | 40.895 us | 0.0804 us | 0.0628 us |
-| Sha256 | Mono | 141.377 us | 0.5598 us | 0.5236 us |
-| | | | | |
-| Md5 | Clr | 18.575 us | 0.0727 us | 0.0644 us |
-| Md5 | Core | 17.562 us | 0.0436 us | 0.0408 us |
-| Md5 | CoreRT | 17.447 us | 0.0293 us | 0.0244 us |
-| Md5 | Mono | 34.500 us | 0.1553 us | 0.1452 us |
+```
+BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19045.2251)
+Intel Core i7-4770HQ CPU 2.20GHz (Haswell), 1 CPU, 8 logical and 4 physical cores
+.NET SDK=7.0.100
+ [Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+ .NET 7.0 : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+ .NET Framework 4.8.1 : .NET Framework 4.8.1 (4.8.9037.0), X64 RyuJIT VectorSize=256
+ Mono : Mono 6.12.0 (Visual Studio), X64 VectorSize=128
+ NativeAOT 7.0 : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+
+| Method | Job | Runtime | Mean | Error | StdDev |
+|------- |--------------------- |--------------------- |----------:|---------:|---------:|
+| Sha256 | .NET 7.0 | .NET 7.0 | 51.90 us | 0.341 us | 0.302 us |
+| Md5 | .NET 7.0 | .NET 7.0 | 21.96 us | 0.052 us | 0.049 us |
+| Sha256 | .NET Framework 4.8.1 | .NET Framework 4.8.1 | 206.33 us | 2.069 us | 1.834 us |
+| Md5 | .NET Framework 4.8.1 | .NET Framework 4.8.1 | 23.28 us | 0.094 us | 0.083 us |
+| Sha256 | Mono | Mono | 167.70 us | 1.216 us | 1.137 us |
+| Md5 | Mono | Mono | 42.12 us | 0.145 us | 0.136 us |
+| Sha256 | NativeAOT 7.0 | NativeAOT 7.0 | 51.45 us | 0.226 us | 0.200 us |
+| Md5 | NativeAOT 7.0 | NativeAOT 7.0 | 21.88 us | 0.050 us | 0.041 us |
```
-There are a lot of predefined jobs which you can use. For example, you can compare `LegacyJitX86` vs `LegacyJitX64` vs `RyuJitX64`:
+There are many predefined job attributes which you can use. For example, you can compare `LegacyJitX86`, `LegacyJitX64`, and `RyuJitX64`:
```cs
[LegacyJitX86Job, LegacyJitX64Job, RyuJitX64Job]
```
-Or you can define own jobs:
+Or, you can define your own jobs:
```cs
[Config(typeof(Config))]
@@ -131,22 +131,22 @@ public class Md5VsSha256
{
public Config()
{
- Add(new Job(EnvMode.LegacyJitX86, EnvMode.Clr, RunMode.Dry)
- {
- Env = { Runtime = Runtime.Clr },
- Run = { LaunchCount = 3, WarmupCount = 5, IterationCount = 10 },
- Accuracy = { MaxStdErrRelative = 0.01 }
- }));
+ AddJob(new Job(Job.Dry)
+ {
+ Environment = { Jit = Jit.LegacyJit, Platform = Platform.X64 },
+ Run = { LaunchCount = 3, WarmupCount = 5, IterationCount = 10 },
+ Accuracy = { MaxRelativeError = 0.01 }
+ });
}
}
```
-Read more: [Jobs](configs/jobs.md), [Configs](configs/configs.md)
+Read more: [Jobs](configs/jobs.md), [Configs](configs/configs.md)
## Columns
-You can also add custom columns to the summary table:
+You can add columns to the summary table:
```cs
[MinColumn, MaxColumn]
@@ -158,13 +158,13 @@ public class Md5VsSha256
| Sha256 | 131.3200 us | 4.6744 us | 129.8216 us | 147.7630 us |
| Md5 | 26.2847 us | 0.4424 us | 25.8442 us | 27.4258 us |
-Of course, you can define own columns based on full benchmark summary.
+You can also define custom columns based on the full benchmark summary.
-Read more: [Columns](configs/columns.md)
+Read more: [Columns](configs/columns.md)
## Exporters
-You can export result of your benchmark in different formats:
+You can export the results of your benchmark in different formats:
```cs
[MarkdownExporter, AsciiDocExporter, HtmlExporter, CsvExporter, RPlotExporter]
@@ -175,11 +175,11 @@ If you have installed R, `RPlotExporter` will generate a lot of nice plots:

-Read more: [Exporters](configs/exporters.md)
+Read more: [Exporters](configs/exporters.md)
## Baseline
-In order to scale your results you need to mark one of your benchmark methods as a `Baseline`:
+To view the relative performance of your benchmarks, mark one of your benchmark methods as the `Baseline`:
```cs
public class Sleeps
@@ -195,7 +195,7 @@ public class Sleeps
}
```
-As a result, you will have additional column in the summary table:
+A new column will be added to the summary table:
| Method | Median | StdDev | Ratio |
| ------- | ----------- | --------- | ------ |
@@ -203,11 +203,11 @@ As a result, you will have additional column in the summary table:
| Time150 | 150.2093 ms | 0.1034 ms | 1.50 |
| Time50 | 50.2509 ms | 0.1153 ms | 0.50 |
-Read more: [Baselines](features/baselines.md)
+Read more: [Baselines](features/baselines.md)
## Params
-You can mark one or several fields or properties in your class by the `Params` attribute. In this attribute, you can specify set of values. As a result, you will get results for each combination of params values.
+You can mark one or several fields or properties in your class with the `Params` attribute. In this attribute, you can specify a set of values. BenchmarkDotNet will run benchmarks for each combination of params values.
```cs
public class IntroParams
@@ -226,6 +226,7 @@ public class IntroParams
}
```
+
| Method | Median | StdDev | A | B |
| --------- | ----------- | --------- | ---- | ---- |
| Benchmark | 115.3325 ms | 0.0242 ms | 100 | 10 |
@@ -233,11 +234,11 @@ public class IntroParams
| Benchmark | 215.3024 ms | 0.0375 ms | 200 | 10 |
| Benchmark | 225.2710 ms | 0.0434 ms | 200 | 20 |
-Read more: [Parameterization](features/parameterization.md)
+Read more: [Parameterization](features/parameterization.md)
## Languages
-You can also write you benchmarks on `F#` or `VB`. Examples:
+You can also write benchmarks in `F#` or `VB`.
```fs
type StringKeyComparison () =
@@ -277,15 +278,16 @@ End Class
## Diagnostics
-A **diagnoser** can attach to your benchmark and get some useful info.
+A diagnoser can attach to your benchmarks and collect additional information.
-The current Diagnosers are:
+Examples of diagnosers built in to BenchmarkDotNet are:
-- GC and Memory Allocation (`MemoryDiagnoser`) which is cross platform, built-in and **is not enabled by default anymore**.
-- JIT Inlining Events (`InliningDiagnoser`). You can find this diagnoser in a separated package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`): [](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/)
+- Garbge collection and allocation statistics (`MemoryDiagnoser`).
+- Lock contention and thread pool statistics (`ThreadingDiagnoser`), which is only available on .NET Core 3.0+.
+- JIT inlining events (`InliningDiagnoser`). You can find this diagnoser in a separated package with diagnosers for Windows (`BenchmarkDotNet.Diagnostics.Windows`): [](https://www.nuget.org/packages/BenchmarkDotNet.Diagnostics.Windows/)
-Below is a sample output from the `MemoryDiagnoser`, note the extra columns on the right-hand side (`Gen 0` and `Allocated`):
+Below is a sample benchmark using `MemoryDiagnoser`. Note the extra columns on the right-hand side (`Gen 0` and `Allocated`):
```
Method | Mean | StdDev | Gen 0 | Allocated |
@@ -294,21 +296,16 @@ Below is a sample output from the `MemoryDiagnoser`, note the extra columns on t
LINQ | 83.0435 ns | 1.0103 ns | 0.0069 | 32 B |
```
-Read more: [Diagnosers](configs/diagnosers.md)
+Read more: [Diagnosers](configs/diagnosers.md)
## BenchmarkRunner
-There are several ways to run your benchmarks: you can use an existing class, run a benchmark based on code from internet or based on source code:
+There are several ways to run your benchmarks.
```cs
var summary = BenchmarkRunner.Run();
var summary = BenchmarkRunner.Run(typeof(MyBenchmarkClass));
-
-string url = "";
-var summary = BenchmarkRunner.RunUrl(url);
-
-string benchmarkSource = "public class MyBenchmarkClass { ...";
-var summary = BenchmarkRunner.RunSource(benchmarkSource);
+var summaries = BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
```
-Read more: [HowToRun](guides/how-to-run.md)
+Read more: [How to run your benchmarks](guides/how-to-run.md)
diff --git a/docs/changelog/toc.yml b/docs/changelog/toc.yml
index 63fee7283a..58da12e376 100644
--- a/docs/changelog/toc.yml
+++ b/docs/changelog/toc.yml
@@ -1,3 +1,5 @@
+- name: v0.13.4
+ href: v0.13.4.md
- name: v0.13.3
href: v0.13.3.md
- name: v0.13.2
diff --git a/docs/docfx.json b/docs/docfx.json
index ffa2071ff7..4f56d3fb3d 100644
--- a/docs/docfx.json
+++ b/docs/docfx.json
@@ -68,7 +68,7 @@
"globalMetadata" :
{
"_appTitle" : "BenchmarkDotNet",
- "_appFooter" : "Copyright © 2013–2021 .NET Foundation and contributors",
+ "_appFooter" : "Copyright © 2013–2023 .NET Foundation and contributors",
"_appLogoPath" : "logo/icon.svg",
"_appFaviconPath": "logo/icon-32.png",
"_enableSearch": false
diff --git a/docs/index.md b/docs/index.md
index c98c2ec1e3..b4c77ae984 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -19,7 +19,7 @@ title: Home
- Features
+ Features
·
Getting started
·
@@ -30,12 +30,12 @@ title: Home
**BenchmarkDotNet** helps you to transform methods into benchmarks, track their performance, and share reproducible measurement experiments.
It's no harder than writing unit tests!
-Under the hood, it performs a lot of [magic](#automation) that guarantees [reliable and precise](#reliability) results thanks to the [perfolizer](https://github.com/AndreyAkinshin/perfolizer) statistical engine.
+Under the hood, it performs a lot of [magic](#Automation) that guarantees [reliable and precise](#Reliability) results thanks to the [perfolizer](https://github.com/AndreyAkinshin/perfolizer) statistical engine.
BenchmarkDotNet protects you from popular benchmarking mistakes and warns you if something is wrong with your benchmark design or obtained measurements.
-The results are presented in a [user-friendly](#friendliness) form that highlights all the important facts about your experiment.
-The library is adopted by [13400+ projects](#who-uses-benchmarkdotnet) including .NET Runtime and supported by the [.NET Foundation](https://dotnetfoundation.org).
+The results are presented in a [user-friendly](#Friendliness) form that highlights all the important facts about your experiment.
+The library is adopted by [13800+ projects](#who-uses-benchmarkdotnet) including .NET Runtime and supported by the [.NET Foundation](https://dotnetfoundation.org).
-It's [easy](#simplicity) to start writing benchmarks, check out an example
+It's [easy](#Simplicity) to start writing benchmarks, check out an example
(copy-pastable version is [here](https://benchmarkdotnet.org/articles/guides/getting-started.html)):
```cs
@@ -79,7 +79,7 @@ Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cor
[Host] : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
Net472 : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
NetCoreApp30 : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
- CoreRt30 : .NET CoreRT 1.0.28231.02 @Commit: 741d61493c560ba96e8151f9e56876d4d3828489, X64 AOT
+ NativeAot70 : .NET 7.0.0-preview.4.22172.7, X64 NativeAOT
Mono : Mono 6.4.0 (Visual Studio), X64
@@ -87,22 +87,22 @@ Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cor
|------- |-------------- |------ |-----------:|----------:|----------:|------:|
| Sha256 | .NET 4.7.2 | 1000 | 7.735 us | 0.1913 us | 0.4034 us | 1.00 |
| Sha256 | .NET Core 3.0 | 1000 | 3.989 us | 0.0796 us | 0.0745 us | 0.50 |
-| Sha256 | CoreRt 3.0 | 1000 | 4.091 us | 0.0811 us | 0.1562 us | 0.53 |
+| Sha256 | NativeAOT 7.0 | 1000 | 4.091 us | 0.0811 us | 0.1562 us | 0.53 |
| Sha256 | Mono | 1000 | 13.117 us | 0.2485 us | 0.5019 us | 1.70 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 1000 | 2.872 us | 0.0552 us | 0.0737 us | 1.00 |
| Md5 | .NET Core 3.0 | 1000 | 1.848 us | 0.0348 us | 0.0326 us | 0.64 |
-| Md5 | CoreRt 3.0 | 1000 | 1.817 us | 0.0359 us | 0.0427 us | 0.63 |
+| Md5 | NativeAOT 7.0 | 1000 | 1.817 us | 0.0359 us | 0.0427 us | 0.63 |
| Md5 | Mono | 1000 | 3.574 us | 0.0678 us | 0.0753 us | 1.24 |
| | | | | | | |
| Sha256 | .NET 4.7.2 | 10000 | 74.509 us | 1.5787 us | 4.6052 us | 1.00 |
| Sha256 | .NET Core 3.0 | 10000 | 36.049 us | 0.7151 us | 1.0025 us | 0.49 |
-| Sha256 | CoreRt 3.0 | 10000 | 36.253 us | 0.7076 us | 0.7571 us | 0.49 |
+| Sha256 | NativeAOT 7.0 | 10000 | 36.253 us | 0.7076 us | 0.7571 us | 0.49 |
| Sha256 | Mono | 10000 | 116.350 us | 2.2555 us | 3.0110 us | 1.58 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 10000 | 17.308 us | 0.3361 us | 0.4250 us | 1.00 |
| Md5 | .NET Core 3.0 | 10000 | 15.726 us | 0.2064 us | 0.1930 us | 0.90 |
-| Md5 | CoreRt 3.0 | 10000 | 15.627 us | 0.2631 us | 0.2461 us | 0.89 |
+| Md5 | NativeAOT 7.0 | 10000 | 15.627 us | 0.2631 us | 0.2461 us | 0.89 |
| Md5 | Mono | 10000 | 30.205 us | 0.5868 us | 0.6522 us | 1.74 |
```
@@ -132,7 +132,7 @@ For example, if you want to [parameterize](https://benchmarkdotnet.org/articles/
and run benchmarks for each case.
If you want to compare benchmarks with each other,
mark one of the benchmark as the [baseline](https://benchmarkdotnet.org/articles/features/baselines.html)
- via `[Benchmark(baseline: true)]`: BenchmarkDotNet will compare it with all of the other benchmarks.
+ via `[Benchmark(Baseline = true)]`: BenchmarkDotNet will compare it with all of the other benchmarks.
If you want to compare performance in different environments, use [jobs](https://benchmarkdotnet.org/articles/configs/jobs.html).
For example, you can run all the benchmarks on .NET Core 3.0 and Mono via
`[SimpleJob(RuntimeMoniker.NetCoreApp30)]` and `[SimpleJob(RuntimeMoniker.Mono)]`.
@@ -141,15 +141,15 @@ If you don't like attributes, you can call most of the APIs via the fluent style
```cs
ManualConfig.CreateEmpty() // A configuration for our benchmarks
- .With(Job.Default // Adding first job
- .With(ClrRuntime.Net472) // .NET Framework 4.7.2
- .With(Platform.X64) // Run as x64 application
- .With(Jit.LegacyJit) // Use LegacyJIT instead of the default RyuJIT
- .WithGcServer(true) // Use Server GC
- ).With(Job.Default // Adding second job
- .AsBaseline() // It will be marked as baseline
- .WithEnvironmentVariable("Key", "Value") // Setting an environment variable
- .WithWarmupCount(0) // Disable warm-up stage
+ .AddJob(Job.Default // Adding first job
+ .WithRuntime(ClrRuntime.Net472) // .NET Framework 4.7.2
+ .WithPlatform(Platform.X64) // Run as x64 application
+ .WithJit(Jit.LegacyJit) // Use LegacyJIT instead of the default RyuJIT
+ .WithGcServer(true) // Use Server GC
+ ).AddJob(Job.Default // Adding second job
+ .AsBaseline() // It will be marked as baseline
+ .WithEnvironmentVariable("Key", "Value") // Setting an environment variable
+ .WithWarmupCount(0) // Disable warm-up stage
);
```
@@ -235,7 +235,7 @@ If you don't customize the summary view,
## Who uses BenchmarkDotNet?
Everyone!
-BenchmarkDotNet is already adopted by more than [13400+](https://github.com/dotnet/BenchmarkDotNet/network/dependents?package_id=UGFja2FnZS0xNTY3MzExMzE%3D) projects including
+BenchmarkDotNet is already adopted by more than [13800+](https://github.com/dotnet/BenchmarkDotNet/network/dependents?package_id=UGFja2FnZS0xNTY3MzExMzE%3D) projects including
[dotnet/performance](https://github.com/dotnet/performance) (reference benchmarks for all .NET Runtimes),
[dotnet/runtime](https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=BenchmarkDotNet) (.NET runtime and libraries),
[Roslyn](https://github.com/dotnet/roslyn/search?q=BenchmarkDotNet&type=Issues&utf8=✓) (C# and Visual Basic compiler),
@@ -270,9 +270,9 @@ BenchmarkDotNet is already adopted by more than [13400+](https://github.com/dotn
[TensorFlow.NET](https://github.com/SciSharp/TensorFlow.NET/tree/master/src/TensorFlowNet.Benchmarks),
[Apache Thrift](https://github.com/apache/thrift/tree/master/lib/netstd/Benchmarks/Thrift.Benchmarks).
On GitHub, you can find
- 10700+ [issues](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=created&type=Issues&utf8=✓),
- 4700+ [commits](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=committer-date&type=Commits&utf8=✓), and
- 1,500,000+ [files](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=indexed&type=Code&utf8=✓)
+ 11400+ [issues](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=created&type=Issues&utf8=✓),
+ 4900+ [commits](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=committer-date&type=Commits&utf8=✓), and
+ 1,550,000+ [files](https://github.com/search?o=desc&q=BenchmarkDotNet+-repo:dotnet%2FBenchmarkDotNet&s=indexed&type=Code&utf8=✓)
that involve BenchmarkDotNet.
## Learn more about benchmarking
diff --git a/src/BenchmarkDotNet.Diagnostics.Windows/InliningDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.Windows/InliningDiagnoser.cs
index 605951f962..4c09957eef 100644
--- a/src/BenchmarkDotNet.Diagnostics.Windows/InliningDiagnoser.cs
+++ b/src/BenchmarkDotNet.Diagnostics.Windows/InliningDiagnoser.cs
@@ -1,12 +1,13 @@
using System.Collections.Generic;
using System.Linq;
+using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Running;
using Microsoft.Diagnostics.Tracing.Session;
namespace BenchmarkDotNet.Diagnostics.Windows
{
- public class InliningDiagnoser : JitDiagnoser
+ public class InliningDiagnoser : JitDiagnoser, IProfiler
{
private static readonly string LogSeparator = new string('-', 20);
@@ -43,6 +44,8 @@ public InliningDiagnoser(bool logFailuresOnly = true, string[] allowedNamespaces
public override IEnumerable Ids => new[] { nameof(InliningDiagnoser) };
+ public string ShortName => "inlining";
+
protected override void AttachToEvents(TraceEventSession session, BenchmarkCase benchmarkCase)
{
defaultNamespace = benchmarkCase.Descriptor.WorkloadMethod.DeclaringType.Namespace;
diff --git a/src/BenchmarkDotNet.Diagnostics.Windows/JitDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.Windows/JitDiagnoser.cs
index ddfb63c27f..b189af0acb 100644
--- a/src/BenchmarkDotNet.Diagnostics.Windows/JitDiagnoser.cs
+++ b/src/BenchmarkDotNet.Diagnostics.Windows/JitDiagnoser.cs
@@ -11,7 +11,7 @@
namespace BenchmarkDotNet.Diagnostics.Windows
{
- public abstract class JitDiagnoser : EtwDiagnoser, IDiagnoser
+ public abstract class JitDiagnoser : EtwDiagnoser, IDiagnoser where TStats : new()
{
protected override ulong EventType => (ulong)ClrTraceEventParser.Keywords.JitTracing;
diff --git a/src/BenchmarkDotNet.Diagnostics.Windows/JitStatsDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.Windows/JitStatsDiagnoser.cs
new file mode 100644
index 0000000000..32be37ed9f
--- /dev/null
+++ b/src/BenchmarkDotNet.Diagnostics.Windows/JitStatsDiagnoser.cs
@@ -0,0 +1,109 @@
+using System.Collections.Generic;
+using System.Threading;
+using BenchmarkDotNet.Columns;
+using BenchmarkDotNet.Diagnosers;
+using BenchmarkDotNet.Reports;
+using BenchmarkDotNet.Running;
+using Microsoft.Diagnostics.Tracing.Parsers;
+using Microsoft.Diagnostics.Tracing.Session;
+
+namespace BenchmarkDotNet.Diagnostics.Windows
+{
+ public class JitStatsDiagnoser : JitDiagnoser, IProfiler
+ {
+ public override IEnumerable Ids => new[] { nameof(JitStatsDiagnoser) };
+
+ public string ShortName => "jit";
+
+ protected override ulong EventType => (ulong)(ClrTraceEventParser.Keywords.Jit | ClrTraceEventParser.Keywords.Compilation);
+
+ public override IEnumerable ProcessResults(DiagnoserResults results)
+ {
+ if (BenchmarkToProcess.TryGetValue(results.BenchmarkCase, out int pid))
+ {
+ if (StatsPerProcess.TryGetValue(pid, out JitStats jitStats))
+ {
+ yield return new Metric(MethodsJittedDescriptor.Instance, jitStats.MethodsCompiled);
+ yield return new Metric(MethodsTieredDescriptor.Instance, jitStats.MethodsTiered);
+ yield return new Metric(JitAllocatedMemoryDescriptor.Instance, jitStats.MemoryAllocated);
+ }
+ }
+ }
+
+ protected override void AttachToEvents(TraceEventSession session, BenchmarkCase benchmarkCase)
+ {
+ session.Source.Clr.MethodJittingStarted += methodData =>
+ {
+ if (StatsPerProcess.TryGetValue(methodData.ProcessID, out JitStats jitStats))
+ {
+ Interlocked.Increment(ref jitStats.MethodsCompiled);
+ }
+ };
+
+ session.Source.Clr.MethodMemoryAllocatedForJitCode += memoryAllocated =>
+ {
+ if (StatsPerProcess.TryGetValue(memoryAllocated.ProcessID, out JitStats jitStats))
+ {
+ Interlocked.Add(ref jitStats.MemoryAllocated, memoryAllocated.AllocatedSizeForJitCode);
+ }
+ };
+
+ session.Source.Clr.TieredCompilationBackgroundJitStart += tieredData =>
+ {
+ if (StatsPerProcess.TryGetValue(tieredData.ProcessID, out JitStats jitStats))
+ {
+ Interlocked.Increment(ref jitStats.MethodsTiered);
+ }
+ };
+ }
+
+ private sealed class MethodsJittedDescriptor : IMetricDescriptor
+ {
+ internal static readonly MethodsJittedDescriptor Instance = new ();
+
+ public string Id => nameof(MethodsJittedDescriptor);
+ public string DisplayName => "Methods JITted";
+ public string Legend => "Total number of methods JITted during entire benchmark execution (including warmup).";
+ public bool TheGreaterTheBetter => false;
+ public string NumberFormat => "N0";
+ public UnitType UnitType => UnitType.Dimensionless;
+ public string Unit => "Count";
+ public int PriorityInCategory => 0;
+ }
+
+ private sealed class MethodsTieredDescriptor : IMetricDescriptor
+ {
+ internal static readonly MethodsTieredDescriptor Instance = new ();
+
+ public string Id => nameof(MethodsTieredDescriptor);
+ public string DisplayName => "Methods Tiered";
+ public string Legend => "Total number of methods re-compiled by Tiered JIT during entire benchmark execution (including warmup).";
+ public bool TheGreaterTheBetter => false;
+ public string NumberFormat => "N0";
+ public UnitType UnitType => UnitType.Dimensionless;
+ public string Unit => "Count";
+ public int PriorityInCategory => 0;
+ }
+
+ private sealed class JitAllocatedMemoryDescriptor : IMetricDescriptor
+ {
+ internal static readonly JitAllocatedMemoryDescriptor Instance = new ();
+
+ public string Id => nameof(JitAllocatedMemoryDescriptor);
+ public string DisplayName => "JIT allocated memory";
+ public string Legend => "Total memory allocated by the JIT during entire benchmark execution (including warmup).";
+ public bool TheGreaterTheBetter => false;
+ public string NumberFormat => "N0";
+ public UnitType UnitType => UnitType.Size;
+ public string Unit => SizeUnit.B.Name;
+ public int PriorityInCategory => 0;
+ }
+ }
+
+ public sealed class JitStats
+ {
+ public long MethodsCompiled;
+ public long MethodsTiered;
+ public long MemoryAllocated;
+ }
+}
diff --git a/src/BenchmarkDotNet.Diagnostics.Windows/TailCallDiagnoser.cs b/src/BenchmarkDotNet.Diagnostics.Windows/TailCallDiagnoser.cs
index 74227fc990..8c76337d20 100644
--- a/src/BenchmarkDotNet.Diagnostics.Windows/TailCallDiagnoser.cs
+++ b/src/BenchmarkDotNet.Diagnostics.Windows/TailCallDiagnoser.cs
@@ -2,6 +2,7 @@
using BenchmarkDotNet.Running;
using Microsoft.Diagnostics.Tracing.Session;
using BenchmarkDotNet.Loggers;
+using BenchmarkDotNet.Diagnosers;
namespace BenchmarkDotNet.Diagnostics.Windows
{
@@ -9,7 +10,7 @@ namespace BenchmarkDotNet.Diagnostics.Windows
/// See MSDN blog post about JIT tracing events
/// and detailed blog post by George Plotnikov for more info
///
- public class TailCallDiagnoser : JitDiagnoser
+ public class TailCallDiagnoser : JitDiagnoser, IProfiler
{
private static readonly string LogSeparator = new string('-', 20);
@@ -32,6 +33,8 @@ public TailCallDiagnoser(bool logFailuresOnly = true, bool filterByNamespace = t
public override IEnumerable Ids => new[] { nameof(TailCallDiagnoser) };
+ public string ShortName => "tail";
+
protected override void AttachToEvents(TraceEventSession traceEventSession, BenchmarkCase benchmarkCase)
{
expectedNamespace = benchmarkCase.Descriptor.WorkloadMethod.DeclaringType.Namespace ?? benchmarkCase.Descriptor.WorkloadMethod.DeclaringType.FullName;
diff --git a/src/BenchmarkDotNet/Diagnosers/DiagnosersLoader.cs b/src/BenchmarkDotNet/Diagnosers/DiagnosersLoader.cs
index 57bb5ee30e..1410aad8bc 100644
--- a/src/BenchmarkDotNet/Diagnosers/DiagnosersLoader.cs
+++ b/src/BenchmarkDotNet/Diagnosers/DiagnosersLoader.cs
@@ -73,6 +73,8 @@ private static IDiagnoser[] LoadWindowsDiagnosers()
return new[]
{
CreateDiagnoser(diagnosticsAssembly, "BenchmarkDotNet.Diagnostics.Windows.InliningDiagnoser"),
+ CreateDiagnoser(diagnosticsAssembly, "BenchmarkDotNet.Diagnostics.Windows.TailCallDiagnoser"),
+ CreateDiagnoser(diagnosticsAssembly, "BenchmarkDotNet.Diagnostics.Windows.JitStatsDiagnoser"),
CreateDiagnoser(diagnosticsAssembly, "BenchmarkDotNet.Diagnostics.Windows.EtwProfiler"),
CreateDiagnoser(diagnosticsAssembly, "BenchmarkDotNet.Diagnostics.Windows.ConcurrencyVisualizerProfiler"),
CreateDiagnoser(diagnosticsAssembly, "BenchmarkDotNet.Diagnostics.Windows.NativeMemoryProfiler")
diff --git a/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs b/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs
index 5bf2e5ed03..3d74a760f4 100644
--- a/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs
+++ b/src/BenchmarkDotNet/Running/BenchmarkRunnerClean.cs
@@ -17,7 +17,6 @@
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Loggers;
using BenchmarkDotNet.Mathematics;
-using BenchmarkDotNet.Portability;
using BenchmarkDotNet.Reports;
using BenchmarkDotNet.Toolchains;
using BenchmarkDotNet.Toolchains.Parameters;
@@ -168,15 +167,13 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,
var cultureInfo = config.CultureInfo ?? DefaultCultureInfo.Instance;
var reports = new List();
string title = GetTitle(new[] { benchmarkRunInfo });
- var consoleTitle = RuntimeInformation.IsWindows() ? Console.Title : string.Empty;
+ using var consoleTitler = new ConsoleTitler($"{benchmarksToRunCount}/{totalBenchmarkCount} Remaining");
logger.WriteLineInfo($"// Found {benchmarks.Length} benchmarks:");
foreach (var benchmark in benchmarks)
logger.WriteLineInfo($"// {benchmark.DisplayInfo}");
logger.WriteLine();
- UpdateTitle(totalBenchmarkCount, benchmarksToRunCount);
-
using (var powerManagementApplier = new PowerManagementApplier(logger))
{
bool stop = false;
@@ -241,15 +238,10 @@ private static Summary Run(BenchmarkRunInfo benchmarkRunInfo,
benchmarksToRunCount -= stop ? benchmarks.Length - i : 1;
- LogProgress(logger, in runsChronometer, totalBenchmarkCount, benchmarksToRunCount, taskbarProgress);
+ LogProgress(logger, in runsChronometer, totalBenchmarkCount, benchmarksToRunCount, consoleTitler, taskbarProgress);
}
}
- if (RuntimeInformation.IsWindows())
- {
- Console.Title = consoleTitle;
- }
-
var runEnd = runsChronometer.GetElapsed();
return new Summary(title,
@@ -652,15 +644,7 @@ private static void Cleanup(HashSet artifactsToCleanup)
}
}
- private static void UpdateTitle(int totalBenchmarkCount, int benchmarksToRunCount)
- {
- if (!Console.IsOutputRedirected && (RuntimeInformation.IsWindows() || RuntimeInformation.IsLinux() || RuntimeInformation.IsMacOS()))
- {
- Console.Title = $"{benchmarksToRunCount}/{totalBenchmarkCount} Remaining";
- }
- }
-
- private static void LogProgress(ILogger logger, in StartedClock runsChronometer, int totalBenchmarkCount, int benchmarksToRunCount, TaskbarProgress taskbarProgress)
+ private static void LogProgress(ILogger logger, in StartedClock runsChronometer, int totalBenchmarkCount, int benchmarksToRunCount, ConsoleTitler consoleTitler, TaskbarProgress taskbarProgress)
{
int executedBenchmarkCount = totalBenchmarkCount - benchmarksToRunCount;
TimeSpan fromNow = GetEstimatedFinishTime(runsChronometer, benchmarksToRunCount, executedBenchmarkCount);
@@ -669,10 +653,8 @@ private static void LogProgress(ILogger logger, in StartedClock runsChronometer,
$" Estimated finish {estimatedEnd:yyyy-MM-dd H:mm} ({(int)fromNow.TotalHours}h {fromNow.Minutes}m from now) **";
logger.WriteLineHeader(message);
- if (!Console.IsOutputRedirected && (RuntimeInformation.IsWindows() || RuntimeInformation.IsLinux() || RuntimeInformation.IsMacOS()))
- {
- Console.Title = $"{benchmarksToRunCount}/{totalBenchmarkCount} Remaining - {(int)fromNow.TotalHours}h {fromNow.Minutes}m to finish";
- }
+ consoleTitler.UpdateTitle ($"{benchmarksToRunCount}/{totalBenchmarkCount} Remaining - {(int)fromNow.TotalHours}h {fromNow.Minutes}m to finish");
+
taskbarProgress.SetProgress((float) executedBenchmarkCount / totalBenchmarkCount);
}
@@ -728,4 +710,4 @@ private static int GetIdToResume(string rootArtifactsFolderPath, string currentL
return -1;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/BenchmarkDotNet/Running/ConsoleTitler.cs b/src/BenchmarkDotNet/Running/ConsoleTitler.cs
new file mode 100644
index 0000000000..7983776e3c
--- /dev/null
+++ b/src/BenchmarkDotNet/Running/ConsoleTitler.cs
@@ -0,0 +1,80 @@
+using System;
+using System.IO;
+using BenchmarkDotNet.Portability;
+
+namespace BenchmarkDotNet.Running
+{
+ ///
+ /// Updates Console.Title, subject to platform capabilities and Console availability.
+ /// Restores the original (or fallback) title upon disposal.
+ ///
+ internal class ConsoleTitler : IDisposable
+ {
+ ///
+ /// Whether this instance has any effect. This will be false if the platform doesn't support Console retitling,
+ /// or if Console output is redirected.
+ ///
+ public bool IsEnabled { get; private set; }
+
+ private string oldConsoleTitle;
+
+ public ConsoleTitler(string initialTitle)
+ {
+ // Return without enabling if Console output is redirected.
+ if (Console.IsOutputRedirected)
+ {
+ return;
+ }
+
+ try
+ {
+ oldConsoleTitle = PlatformSupportsTitleRead() ? Console.Title : "";
+ }
+ catch (IOException)
+ {
+ // We're unable to read Console.Title on a platform that supports it. This can happen when no console
+ // window is available due to the application being Windows Forms, WPF, Windows Service or a daemon.
+ oldConsoleTitle = "";
+ }
+
+ try
+ {
+ // Enable ConsoleTitler if and only if we can successfully set the Console.Title property.
+ Console.Title = initialTitle;
+ IsEnabled = true;
+ }
+ catch (IOException)
+ {
+ }
+ catch (PlatformNotSupportedException)
+ {
+ // As of .NET 7, platforms other than Windows, Linux and MacOS do not support Console retitling.
+ }
+ }
+
+#if NET6_0_OR_GREATER
+ [System.Runtime.Versioning.SupportedOSPlatformGuard("windows")]
+#endif
+ private static bool PlatformSupportsTitleRead() => RuntimeInformation.IsWindows();
+
+ ///
+ /// Updates Console.Title if enabled.
+ ///
+ public void UpdateTitle(string title)
+ {
+ if (IsEnabled)
+ {
+ Console.Title = title;
+ }
+ }
+
+ public void Dispose()
+ {
+ if (IsEnabled)
+ {
+ Console.Title = oldConsoleTitle;
+ IsEnabled = false;
+ }
+ }
+ }
+}