Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions docs/benchmarkdotnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ py .\scripts\benchmarks_ci.py --frameworks netcoreapp3.0

### Interactive Mode

To run the benchmarks in interactive mode you have to execute `dotnet run -f $targetFrameworkMoniker` in the folder with benchmarks project.
To run the benchmarks in interactive mode you have to execute `dotnet run -c Release -f $targetFrameworkMoniker` in the folder with benchmarks project.

```cmd
C:\Projects\performance\src\benchmarks\micro> dotnet run -f netcoreapp3.0
C:\Projects\performance\src\benchmarks\micro> dotnet run -c Release -f netcoreapp3.0
Available Benchmarks:
#0 Burgers
#1 ByteMark
Expand Down Expand Up @@ -117,40 +117,40 @@ You can filter the benchmarks using `--filter $globPattern` console line argumen

The glob patterns are applied to full benchmark name: namespace.typeName.methodName. Examples:

1. Run all the benchmarks from BenchmarksGame namespace:
- Run all the benchmarks from BenchmarksGame namespace:

```cmd
dotnet run -f netcoreapp3.0 --filter BenchmarksGame*
dotnet run -c Release -f netcoreapp3.0 --filter BenchmarksGame*
```

2. Run all the benchmarks with type name Richards:
- Run all the benchmarks with type name Richards:

```cmd
dotnet run -f netcoreapp3.0 --filter *.Richards.*
dotnet run -c Release -f netcoreapp3.0 --filter *.Richards.*
```

3. Run all the benchmarks with method name ToStream:
- Run all the benchmarks with method name ToStream:

```cmd
dotnet run -f netcoreapp3.0 --filter *.ToStream
dotnet run -c Release -f netcoreapp3.0 --filter *.ToStream
```

4. Run ALL benchmarks:
- Run ALL benchmarks:

```cmd
dotnet run -f netcoreapp3.0 --filter *
dotnet run -c Release -f netcoreapp3.0 --filter *
```

5. You can provide many filters (logical disjunction):
- You can provide many filters (logical disjunction):

```cmd
dotnet run -f netcoreapp3.0 --filter System.Collections*.Dictionary* *.Perf_Dictionary.*
dotnet run -c Release -f netcoreapp3.0 --filter System.Collections*.Dictionary* *.Perf_Dictionary.*
```

6. To print a **joined summary** for all of the benchmarks (by default printed per type), use `--join`:
- To print a **joined summary** for all of the benchmarks (by default printed per type), use `--join`:

```cmd
dotnet run -f netcoreapp2.1 --filter BenchmarksGame* --join
dotnet run -c Release -f netcoreapp2.1 --filter BenchmarksGame* --join
```

Please remember that on **Unix** systems `*` is resolved to all files in current directory, so you need to escape it `'*'`.
Expand All @@ -162,7 +162,7 @@ To print the list of all available benchmarks you need to pass `--list [tree/fla
Example: Show the tree of all the benchmarks from System.Threading namespace that can be run for .NET Core 2.0:

```cmd
dotnet run -f netcoreapp2.0 --list tree --filter System.Threading*
dotnet run -c Release -f netcoreapp2.0 --list tree --filter System.Threading*
```

```log
Expand Down Expand Up @@ -257,7 +257,7 @@ If you want to disassemble the benchmarked code, you need to use the [Disassembl

You can do that by passing `--disassm` to the app or by using `[DisassemblyDiagnoser(printAsm: true, printSource: true)]` attribute or by adding it to your config with `config.With(DisassemblyDiagnoser.Create(new DisassemblyDiagnoserConfig(printAsm: true, recursiveDepth: 1))`.

Example: `dotnet run -f netcoreapp2.0 -- --filter System.Memory.Span<Int32>.Reverse -d`
Example: `dotnet run -c Release -f netcoreapp2.0 -- --filter System.Memory.Span<Int32>.Reverse -d`

```assembly
; System.Runtime.InteropServices.MemoryMarshal.GetReference[[System.Byte, System.Private.CoreLib]](System.Span`1<Byte>)
Expand Down Expand Up @@ -288,7 +288,7 @@ Available options are: Mono, CoreRT, net461, net462, net47, net471, net472, netc
Example: run the benchmarks for .NET Core 2.2 and 3.0:

```cmd
dotnet run -f netcoreapp2.2 --runtimes netcoreapp2.1 netcoreapp3.0
dotnet run -c Release -f netcoreapp2.2 --runtimes netcoreapp2.1 netcoreapp3.0
```

**Important: The host process needs to be the lowest common API denominator of the runtimes you want to compare!** In this case, it was`netcoreapp2.2`.
Expand All @@ -300,7 +300,7 @@ To perform a Mann–Whitney U Test and display the results in a dedicated column
Example: run Mann–Whitney U test with relative ratio of 5% for `BinaryTrees_2` for .NET Core 2.1 (base) vs .NET Core 2.2 (diff). .NET Core 2.1 will be baseline because it was first.

```cmd
dotnet run -f netcoreapp2.1 --filter *BinaryTrees_2* --runtimes netcoreapp2.1 netcoreapp2.2 --statisticalTest 5%
dotnet run -c Release -f netcoreapp2.1 --filter *BinaryTrees_2* --runtimes netcoreapp2.1 netcoreapp2.2 --statisticalTest 5%
```

| Method | Toolchain | Mean | MannWhitney(5%) |
Expand All @@ -327,7 +327,7 @@ Please use this option only when you are sure that the benchmarks you want to ru
It's possible to benchmark private builds of CoreCLR/FX using CoreRun.

```cmd
dotnet run -f netcoreapp3.0 --coreRun $thePath
dotnet run -c Release -f netcoreapp3.0 --coreRun $thePath
```

**Note:** You can provide more than 1 path to CoreRun. In such case, the first path will be the baseline and all the benchmarks are going to be executed for all CoreRuns you have specified.
Expand All @@ -353,7 +353,7 @@ public void PrintInfo()
You can also use any dotnet cli to build and run the benchmarks.

```cmd
dotnet run -f netcoreapp3.0 --cli "C:\Projects\performance\.dotnet\dotnet.exe"
dotnet run -c Release -f netcoreapp3.0 --cli "C:\Projects\performance\.dotnet\dotnet.exe"
```

This is very useful when you want to compare different builds of .NET Core SDK.
Expand All @@ -365,7 +365,7 @@ It's possible to benchmark a private build of .NET Runtime. You just need to pas
So if you made a change in CLR and want to measure the difference, you can run the benchmarks with:

```cmd
dotnet run -f net472 -- --clrVersion $theVersion
dotnet run -c Release -f net472 -- --clrVersion $theVersion
```

More info can be found [here](https://github.com/dotnet/BenchmarkDotNet/issues/706).
Expand All @@ -375,5 +375,5 @@ More info can be found [here](https://github.com/dotnet/BenchmarkDotNet/issues/7
To run benchmarks with private CoreRT build you need to provide the `IlcPath`. Example:

```cmd
dotnet run -f netcoreapp2.1 -- --ilcPath C:\Projects\corert\bin\Windows_NT.x64.Release
dotnet run -c Release -f netcoreapp2.1 -- --ilcPath C:\Projects\corert\bin\Windows_NT.x64.Release
```
15 changes: 8 additions & 7 deletions docs/benchmarking-workflow-corefx.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ During the port from xunit-performance to BenchmarkDotNet, the namespaces, type
Please remember that you can filter the benchmarks using a glob pattern applied to namespace.typeName.methodName ([read more](./benchmarkdotnet.md#Filtering-the-Benchmarks)):

```cmd
dotnet run -f netcoreapp3.0 --filter System.Memory*
dotnet run -c Release -f netcoreapp3.0 --filter System.Memory*
```

Moreover, every CoreFX benchmark belongs to a [CoreFX category](../src/benchmarks/micro/README.md#Categories)
Expand All @@ -84,7 +84,7 @@ C:\Projects\corefx> build -c Release
Every time you want to run the benchmarks against local build of CoreFX you need to provide the path to CoreRun:

```cmd
dotnet run -f netcoreapp3.0 --coreRun "C:\Projects\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe" --filter $someFilter
dotnet run -c Release -f netcoreapp3.0 --coreRun "C:\Projects\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe" --filter $someFilter
```

**Note:** BenchmarkDotNet expects a path to `CoreRun.exe` file (`corerun` on Unix), not to `Core_Root` folder.
Expand All @@ -102,7 +102,8 @@ Preventing regressions is a fundamental part of our performance culture. The che
**Before introducing any changes that may impact performance**, you should run the benchmarks that test the performance of the feature that you are going to work on and store the results in a **dedicated** folder.

```cmd
C:\Projects\performance\src\benchmarks\micro> dotnet run -f netcoreapp3.0 \
C:\Projects\performance\src\benchmarks\micro> dotnet run -c Release \
-f netcoreapp3.0 \
--artifacts "C:\results\before" \
--coreRun "C:\Projects\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe" \
--filter System.IO.Pipes*
Expand All @@ -117,7 +118,8 @@ After you introduce the changes and rebuild the part of CoreFX that you are work
```cmd
C:\Projects\corefx\src\System.IO.Pipes\src> dotnet msbuild /p:ConfigurationGroup=Release

C:\Projects\performance\src\benchmarks\micro> dotnet run -f netcoreapp3.0 \
C:\Projects\performance\src\benchmarks\micro> dotnet run -c Release \
-f netcoreapp3.0 \
--artifacts "C:\results\after" \
--coreRun "C:\Projects\corefx\artifacts\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe" \
--filter System.IO.Pipes*
Expand Down Expand Up @@ -161,8 +163,8 @@ The next step is to send a PR to this repository with the aforementioned benchma

The real performance investigation starts with profiling. To profile the benchmarked code and produce an ETW Trace file ([read more](./benchmarkdotnet.md#Profiling)):

```
dotnet run -f netcoreapp3.0 --profiler ETW --filter $YourFilter
```cmd
Comment thread
billwert marked this conversation as resolved.
dotnet run -c Release -f netcoreapp3.0 --profiler ETW --filter $YourFilter
```

The benchmarking tool is going to print the path to the `.etl` trace file. You should open it with PerfView or Windows Performance Analyzer and start the analysis from there. If you are not familiar with PerfView, you should watch [PerfView Tutorial](https://channel9.msdn.com/Series/PerfView-Tutorial) by @vancem first. It's an investment that is going to pay off very quickly.
Expand Down Expand Up @@ -240,7 +242,6 @@ namespace System
public static class Console
{
public static void WriteHelloWorld() => WriteLine("Hello World!");

// the rest omitted for brevity
}
}
Expand Down
34 changes: 17 additions & 17 deletions docs/benchmarking-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Sample commands:
- See the list of all available .NET Core 2.1 System.Linq benchmarks:

```cmd
dotnet run -f netcoreapp2.1 -- -f System.Linq* --list flat
dotnet run -c Release -f netcoreapp2.1 -- -f System.Linq* --list flat
```

```log
Expand Down Expand Up @@ -106,7 +106,7 @@ System.Linq.Tests.Perf_Linq.Range
- See a hierarchy tree of all available .NET Core 3.0 System.IO.Compression benchmarks:

```cmd
dotnet run -f netcoreapp3.0 -- -f System.IO.Compression* --list tree
dotnet run -c Release -f netcoreapp3.0 -- -f System.IO.Compression* --list tree
```

```log
Expand All @@ -131,7 +131,7 @@ System
- See a list of all the benchmarks which belong to BenchmarksGame category:

```cmd
dotnet run -f netcoreapp2.1 -- --allCategories BenchmarksGame --list flat
dotnet run -c Release -f netcoreapp2.1 -- --allCategories BenchmarksGame --list flat
```

```log
Expand Down Expand Up @@ -168,7 +168,7 @@ Just specify the target framework moniker for `dotnet run`.
Example: run `System.Collections.CopyTo<Int32>.Array` benchmarks against .NET Core 2.1 installed on your machine:

```cmd
dotnet run -f netcoreapp2.1 -- -f System.Collections.CopyTo<Int32>.Array
dotnet run -c Release -f netcoreapp2.1 -- -f System.Collections.CopyTo<Int32>.Array
```

### Against multiple runtimes
Expand All @@ -178,21 +178,21 @@ You need to specify the target framework monikers via `--runtimes` or just `-r`
Example: run `System.Collections.CopyTo<Int32>.Array` benchmarks against .NET Core 2.0 and 2.1 installed on your machine:

```cmd
dotnet run -f netcoreapp2.0 -- -f System.Collections.CopyTo<Int32>.Array --runtimes netcoreapp2.0 netcoreapp2.1
dotnet run -c Release -f netcoreapp2.0 -- -f System.Collections.CopyTo<Int32>.Array --runtimes netcoreapp2.0 netcoreapp2.1
```

**Important:** when comparing few different .NET runtimes please always use the lowest common API denominator as the host process. What does it mean? BDN needs to detect and build these benchmarks. If you run the host process as .NET Core 2.1 it won't be able to detect benchmarks that use newer APIs are available only for .NET Core 3.0.

Example: run benchmarks for APIs available in .NET Core 2.1 using .NET Core 3.0

```cmd
dotnet run -f netcoreapp2.1 -- -r netcoreapp3.0
dotnet run -c Release -f netcoreapp2.1 -- -r netcoreapp3.0
```

Example: run benchmarks for APIs available in .NET Core 3.0 using .NET Core 3.0

```cmd
dotnet run -f netcoreapp3.0
dotnet run -c Release -f netcoreapp3.0
```

### Against single runtime using given dotnet cli
Expand All @@ -202,7 +202,7 @@ Specify the target framework moniker for `dotnet run` and the path to `dotnet cl
Example: run `System.Collections.CopyTo<Int32>.Array` benchmarks against .NET Core 3.0 downloaded to a given location:

```cmd
dotnet run -f netcoreapp3.0 -- -f System.Collections.CopyTo<Int32>.Array --cli C:\tmp\dotnetcli\dotnet.exe
dotnet run -c Release -f netcoreapp3.0 -- -f System.Collections.CopyTo<Int32>.Array --cli C:\tmp\dotnetcli\dotnet.exe
```

### Against private runtime build
Expand All @@ -217,7 +217,7 @@ Pass the path to CoreRun using `--coreRun` argument. In both CoreCLR and CoreFX
Example: Run all CoreCLR benchmarks using "C:\Projects\corefx\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe"

```cmd
dotnet run -f netcoreapp3.0 -- --allCategories CoreCLR --coreRun "C:\Projects\corefx\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe"
dotnet run -c Release -f netcoreapp3.0 -- --allCategories CoreCLR --coreRun "C:\Projects\corefx\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe"
```

If you want to use some non-default dotnet cli (or you just don't have a default dotnet cli) to build the benchmarks pass the path to cli via `--cli`.
Expand All @@ -226,7 +226,7 @@ If you want restore the packages to selected folder, pass it via `--packages`.
Example: Run all CoreCLR benchmarks using "C:\Projects\coreclr\bin\tests\Windows_NT.x64.Release\Tests\Core_Root\CoreRun.exe", restore the packages to C:\Projects\coreclr\packages and use "C:\Projects\coreclr\Tools\dotnetcli\dotnet.exe" for building the benchmarks.

```cmd
dotnet run -f netcoreapp3.0 -- --allCategories CoreCLR --coreRun "C:\Projects\coreclr\bin\tests\Windows_NT.x64.Release\Tests\Core_Root\CoreRun.exe --cli "C:\Projects\coreclr\Tools\dotnetcli\dotnet.exe" --packages "C:\Projects\coreclr\packages"
dotnet run -c Release -f netcoreapp3.0 -- --allCategories CoreCLR --coreRun "C:\Projects\coreclr\bin\tests\Windows_NT.x64.Release\Tests\Core_Root\CoreRun.exe --cli "C:\Projects\coreclr\Tools\dotnetcli\dotnet.exe" --packages "C:\Projects\coreclr\packages"
```

**VERY IMPORTANT**: CoreRun is a simple host that does NOT take any dependency on NuGet. BenchmarkDotNet just generates some boilerplate code, builds it and tells CoreRun.exe to run the benchmarks from the auto-generated library. CoreRun runs the benchmarks using the libraries that are placed in it's folder. When benchmarked code has a dependency to `System.ABC.dll` version 4.5 and CoreRun has `System.ABC.dll` version 4.5.1 in it's folder, then CoreRun is going to load and use `System.ABC.dll` version 4.5.1. This is why having a single clone of .NET Performance repository allows you to run benchmarks against private builds of CoreCLR/FX from many different locations.
Expand Down Expand Up @@ -254,7 +254,7 @@ By using the `DisassemblyDiagnoser` and `EtwProfiler` you should be able to get
5. run the benchmarks using given `CoreRun.exe` and save the results to a dedicated folder. An example:

```cmd
dotnet run -f netcoreapp3.0 --
dotnet run -c Release -f netcoreapp3.0 --
--artifacts before
--filter *Span*
--coreRun "C:\Projects\corefx\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe"
Expand All @@ -267,7 +267,7 @@ By using the `DisassemblyDiagnoser` and `EtwProfiler` you should be able to get
7. Run the benchmarks using given `CoreRun.exe` and save the results to a dedicated folder. **Different one that you used to store results previously!** Example:

```cmd
dotnet run -f netcoreapp3.0 -- --artifacts after --filter *Span* --coreRun "C:\Projects\corefx\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe"
dotnet run -c Release -f netcoreapp3.0 -- --artifacts after --filter *Span* --coreRun "C:\Projects\corefx\bin\runtime\netcoreapp-Windows_NT-Release-x64\CoreRun.exe"
```

8. Compare the results using [Results Comparer](../src/tools/ResultsComparer/README.md)
Expand All @@ -289,7 +289,7 @@ Example: run Mann–Whitney U test with an absolute ratio of 3 milliseconds and
The following commands are represented in a few lines to make it easier to read on GitHub. Please remove the new lines when copy-pasting to console.

```cmd
dotnet run -f netcoreapp3.0 \
dotnet run -c Release -f netcoreapp3.0 \
--allCategories BenchmarksGame \
--statisticalTest 3ms \
--coreRun \
Expand All @@ -300,7 +300,7 @@ dotnet run -f netcoreapp3.0 \
Example: run all benchmarks for .NET Core 2.1 vs 2.2 and use Mann–Whitney U test with a relative ratio of 5%.

```cmd
dotnet run -f netcoreapp2.1 --
dotnet run -c Release -f netcoreapp2.1 --
--filter *
--statisticalTest 5%
--runtimes netcoreapp2.1 netcoreapp2.2
Expand All @@ -317,19 +317,19 @@ A must read is [running benchmarks against multiple runtimes](#Against-multiple-
Example: run all `Span` benchmarks for .NET Core 2.1 vs 3.0:

```cmd
dotnet run -f netcoreapp2.1 -- --allCategories Span --runtimes netcoreapp2.1 netcoreapp3.0
dotnet run -c Release -f netcoreapp2.1 -- --allCategories Span --runtimes netcoreapp2.1 netcoreapp3.0
```

Example: run all `System.IO` benchmarks for .NET 4.7.2 vs .NET Core 3.0 preview using dotnet cli from given location:

```cmd
dotnet run -f net472 -- --filter System.IO* --runtimes net472 netcoreapp3.0 --cli "C:\Downloads\3.0.0-preview1-03129-01\dotnet.exe"
dotnet run -c Release -f net472 -- --filter System.IO* --runtimes net472 netcoreapp3.0 --cli "C:\Downloads\3.0.0-preview1-03129-01\dotnet.exe"
```

Example: run all benchmarks for .NET Core 2.1 vs 2.2:

```cmd
dotnet run -f netcoreapp2.1 -- -f * --runtimes netcoreapp2.1 netcoreapp2.2
dotnet run -c Release -f netcoreapp2.1 -- -f * --runtimes netcoreapp2.1 netcoreapp2.2
```

### New API
Expand Down
14 changes: 7 additions & 7 deletions src/benchmarks/micro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,45 @@ The first thing that you need to choose is the Target Framework. Available optio
To run the benchmarks in Interactive Mode, where you will be asked which benchmark(s) to run:

```cmd
dotnet run -f netcoreapp3.0
dotnet run -c Release -f netcoreapp3.0
```

To list all available benchmarks ([read more](../../../docs/benchmarkdotnet.md#Listing-the-Benchmarks)):

```cmd
dotnet run -f netcoreapp3.0 --list flat|tree
dotnet run -c Release -f netcoreapp3.0 --list flat|tree
```

To filter the benchmarks using a glob pattern applied to namespace.typeName.methodName ([read more](../../../docs/benchmarkdotnet.md#Filtering-the-Benchmarks)):

```cmd
dotnet run -f netcoreapp3.0 --filter *Span*
dotnet run -c Release -f netcoreapp3.0 --filter *Span*
```

To profile the benchmarked code and produce an ETW Trace file ([read more](../../../docs/benchmarkdotnet.md#Profiling)):

```cmd
dotnet run -f netcoreapp3.0 --filter $YourFilter --profiler ETW
dotnet run -c Release -f netcoreapp3.0 --filter $YourFilter --profiler ETW
```

To run the benchmarks for multiple runtimes ([read more](../../../docs/benchmarkdotnet.md#Multiple-Runtimes)):

```cmd
dotnet run -f netcoreapp2.1 --filter * --runtimes netcoreapp2.1 netcoreapp3.0 corert
dotnet run -c Release -f netcoreapp2.1 --filter * --runtimes netcoreapp2.1 netcoreapp3.0 corert
```

## Private Runtime Builds

If you contribute to CoreFX/CoreCLR and want to benchmark **local builds of .NET Core** you need to build CoreFX/CoreCLR in Release (including tests) and then provide the path(s) to CoreRun(s). Provided CoreRun(s) will be used to execute every benchmark in a dedicated process:

```cmd
dotnet run -f netcoreapp3.0 --filter $YourFilter --coreRun "C:\Projects\coreclr\bin\tests\Windows_NT.x64.Release\Tests\Core_Root\CoreRun.exe"
dotnet run -c Release -f netcoreapp3.0 --filter $YourFilter --coreRun "C:\Projects\coreclr\bin\tests\Windows_NT.x64.Release\Tests\Core_Root\CoreRun.exe"
```

To make sure that your changes don't introduce any regressions, you can provide paths to CoreRuns with and without your changes and use the Statistical Test feature to detect regressions/improvements ([read more](../../../docs/benchmarkdotnet.md#Regressions)):

```cmd
dotnet run -f netcoreapp3.0 \
dotnet run -c Release -f netcoreapp3.0 \
--filter BenchmarksGame* \
--statisticalTest 3ms \
--coreRun \
Expand Down