It's been a year since our last release. BenchmarkDotNet has been downloaded more than seven million times from [nuget.org](https://www.nuget.org/packages/BenchmarkDotNet/). It's more than we could have ever possibly imagined! Some could say, that it's also more than we can handle ;) That is why we wanted to once again thank [all the contributors](https://github.com/dotnet/BenchmarkDotNet/graphs/contributors) who helped us with `0.13.0` release!

## Highlights

In BenchmarkDotNet v0.13.0, we have supported various technologies:

* .NET 5 and .NET 6 target framework monikers
* .NET SDK installed via snap
* SingleFile deployment
* Xamarin applications
* WASM applications
* Mono AOT

We have also introduced new features and improvements including:

* Memory randomization
* Method-specific job attributes
* Sortable parameter columns
* Customizable ratio column
* Improved CoreRun and CoreRT support
* Improved Hardware Counters support

Of course, this release includes dozens of other improvements and bug fixes!

## Supported technologies

### .NET 5, .NET 6, SingleFile and snap

At some point in time, `netcoreapp5.0` moniker was changed to `net5.0`, which required a fix on our side ([#1479](https://github.com/dotnet/BenchmarkDotNet/pull/1479), btw we love this kind of changes). Moreover, .NET 5 introduced platform-specific TMFs (example:  `net5.0-windows10.0.19041.0`) which also required some extra work: [#1560](https://github.com/dotnet/BenchmarkDotNet/pull/1560), [#1691](https://github.com/dotnet/BenchmarkDotNet/pull/1691).


 In [#1523](https://github.com/dotnet/BenchmarkDotNet/pull/1523) support for .NET 6 was added.

```xml
<TargetFrameworks>net5.0;net5.0-windows10.0.19041.0;net6.0<TargetFrameworks>
```

In [#1686](https://github.com/dotnet/BenchmarkDotNet/pull/1686) [@am11](https://github.com/am11) has implemented support for **single file deployment** (supported in .NET 5 onwards).

Last, but not least in [#1652](https://github.com/dotnet/BenchmarkDotNet/pull/1652) **snap** support has been implemented.

```log
adam@adsitnik-ubuntu:~/projects/BenchmarkDotNet/samples/BenchmarkDotNet.Samples$ dotnet50 run -c Release -f net5.0 --filter BenchmarkDotNet.Samples.IntroColdStart.Foo
// Validating benchmarks:
// ***** BenchmarkRunner: Start   *****
// ***** Found 1 benchmark(s) in total *****
// ***** Building 1 exe(s) in Parallel: Start   *****
// start /snap/dotnet-sdk/112/dotnet restore  /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in /home/adam/projects/BenchmarkDotNet/samples/BenchmarkDotNet.Samples/bin/Release/net5.0/9a018ee4-0f33-46dd-9093-01d3bf31233b
// command took 1.49s and exited with 0
// start /snap/dotnet-sdk/112/dotnet build -c Release  --no-restore /p:UseSharedCompilation=false /p:BuildInParallel=false /m:1 /p:Deterministic=true /p:Optimize=true in /home/adam/projects/BenchmarkDotNet/samples/BenchmarkDotNet.Samples/bin/Release/net5.0/9a018ee4-0f33-46dd-9093-01d3bf31233b
// command took 2.78s and exited with 0
// ***** Done, took 00:00:04 (4.37 sec)   *****
// Found 1 benchmarks:
//   IntroColdStart.Foo: Job-NECTOD(IterationCount=5, RunStrategy=ColdStart)

// **************************
// Benchmark: IntroColdStart.Foo: Job-NECTOD(IterationCount=5, RunStrategy=ColdStart)
// *** Execute ***
// Launch: 1 / 1
// Execute: /snap/dotnet-sdk/112/dotnet "9a018ee4-0f33-46dd-9093-01d3bf31233b.dll" --benchmarkName "BenchmarkDotNet.Samples.IntroColdStart.Foo" --job "IterationCount=5, RunStrategy=ColdStart" --benchmarkId 0 in /home/adam/projects/BenchmarkDotNet/samples/BenchmarkDotNet.Samples/bin/Release/net5.0/9a018ee4-0f33-46dd-9093-01d3bf31233b/bin/Release/net5.0
```

### Xamarin support

Thanks to the contributions of the amazing [@jonathanpeppers](https://github.com/jonathanpeppers) BenchmarkDotNet supports Xamarin! The examples can be found in our repo: [iOS](https://github.com/dotnet/BenchmarkDotNet/tree/master/samples/BenchmarkDotNet.Samples.iOS), [Android](https://github.com/dotnet/BenchmarkDotNet/tree/master/samples/BenchmarkDotNet.Samples.Android).

![](https://user-images.githubusercontent.com/840039/73184210-b105fb80-40e1-11ea-9efb-d29fe4d08c79.png#mid)

[#1360](https://github.com/dotnet/BenchmarkDotNet/pull/1360), [#1429](https://github.com/dotnet/BenchmarkDotNet/pull/1429), [#1434](https://github.com/dotnet/BenchmarkDotNet/pull/1434), [#1509](https://github.com/dotnet/BenchmarkDotNet/pull/1509)

### WASM support

Thanks to the work of [@naricc](https://github.com/naricc) you can now benchmark WASM using Mono Runtime! For more details, please refer to our [docs](https://benchmarkdotnet.org/articles/configs/toolchains.html#Wasm).

![](https://user-images.githubusercontent.com/6011991/87671577-dd860080-c771-11ea-922f-e26a32a3f831.png#mid)

[#1483](https://github.com/dotnet/BenchmarkDotNet/pull/1483), [#1498](https://github.com/dotnet/BenchmarkDotNet/pull/1498), [#1500](https://github.com/dotnet/BenchmarkDotNet/pull/1500), [#1501](https://github.com/dotnet/BenchmarkDotNet/pull/1501), [#1507](https://github.com/dotnet/BenchmarkDotNet/pull/1507), [#1592](https://github.com/dotnet/BenchmarkDotNet/pull/1592), [#1689](https://github.com/dotnet/BenchmarkDotNet/pull/1689).

### Mono AOT support

In another awesome contribution ([#1662](https://github.com/dotnet/BenchmarkDotNet/pull/1662)) [@naricc](https://github.com/naricc) has implemented Mono AOT support. The new toolchain supports doing Mono AOT runs with both the Mono-Mini compiler and the Mono-LLVM compiler (which uses LLVM on the back end).

 For more details, please go to our [docs](https://benchmarkdotnet.org/articles/configs/toolchains.html#MonoAotLLVM).

## New features and improvements

### Memory randomization

In [#1587](https://github.com/dotnet/BenchmarkDotNet/pull/1587) [@adamsitnik](https://github.com/adamsitnik) has introduced a new, **experimental** feature called "Memory Randomization".

This feature allows you to ask BenchmarkDotNet to randomize the memory alignment by allocating random-sized byte arrays between iterations and **call [GlobalSetup] before every benchmark iteration** and `[GlobalCleanup]` after every benchmark iteration.

Sample benchmark:

```cs
public class IntroMemoryRandomization
{
    [Params(512 * 4)]
    public int Size;

    private int[] _array;
    private int[] _destination;

    [GlobalSetup]
    public void Setup()
    {
        _array = new int[Size];
        _destination = new int[Size];
    }

    [Benchmark]
    public void Array() => System.Array.Copy(_array, _destination, Size);
}
```

Without asking for the randomization, the objects are allocated in `[GlobalSetup]` and their unmodified addresses (and alignment) are used for all iterations (as long as they are not promoted to an older generation by the GC). This is typically the desired behavior, as it gives you very nice and flat distributions:

```cmd
dotnet run -c Release --filter IntroMemoryRandomization
```

```ini
-------------------- Histogram --------------------
[502.859 ns ; 508.045 ns) | @@@@@@@@@@@@@@@
---------------------------------------------------
```

But if for some reason you are interested in getting a distribution that is better reflecting the "real-life" performance you can enable the randomization:

```cmd
dotnet run -c Release --filter IntroMemoryRandomization --memoryRandomization true
```

```ini
-------------------- Histogram --------------------
[108.803 ns ; 213.537 ns) | @@@@@@@@@@@@@@@
[213.537 ns ; 315.458 ns) |
[315.458 ns ; 446.853 ns) | @@@@@@@@@@@@@@@@@@@@
[446.853 ns ; 559.259 ns) | @@@@@@@@@@@@@@@
---------------------------------------------------
```

### Method-specific job attributes

From now, all attributes that derive from `JobMutatorConfigBaseAttribute` ([full list](https://benchmarkdotnet.org/api/BenchmarkDotNet.Attributes.JobMutatorConfigBaseAttribute.html#BenchmarkDotNet_Attributes_JobMutatorConfigBaseAttribute)) can be applied to methods. You no longer have to move a method to a separate type to customize config for it.

```cs
[Benchmark]
[WarmupCount(1)]
public void SingleWarmupIteration()

[Benchmark]
[WarmupCount(9)]
public void NineWarmupIterations()
```

### Sortable parameter columns

In order to sort columns of parameters in the results table, you can use the Property `Priority` inside the params attribute. The priority range is `[Int32.MinValue;Int32.MaxValue]`, lower priorities will appear earlier in the column order. The default priority is set to `0`.

```cs
public class IntroParamsPriority
{
    [Params(100)]
    public int A { get; set; }

    [Params(10, Priority = -100)]
    public int B { get; set; }

    [Benchmark]
    public void Benchmark() => Thread.Sleep(A + B + 5);
}
```

|    Method |  B |   A |     Mean |   Error |  StdDev |
|---------- |--- |---- |---------:|--------:|--------:|
| Benchmark | 10 | 100 | 115.4 ms | 0.12 ms | 0.11 ms |


This feature got implemented by [@JohannesDeml](https://github.com/JohannesDeml) in [#1612](https://github.com/dotnet/BenchmarkDotNet/pull/1612).

### Customizable ratio column

Now it's possible to customize the format of the ratio column.

```cs
[Config(typeof(Config))]
public class IntroRatioStyle
{
    [Benchmark(Baseline = true)]
    public void Baseline() => Thread.Sleep(1000);

    [Benchmark]
    public void Bar() => Thread.Sleep(150);

    [Benchmark]
    public void Foo() => Thread.Sleep(1150);

    private class Config : ManualConfig
    {
        public Config()
        {
            SummaryStyle = SummaryStyle.Default.WithRatioStyle(RatioStyle.Trend);
        }
    }
}
```

```
|   Method |       Mean |   Error |  StdDev |        Ratio | RatioSD |
|--------- |-----------:|--------:|--------:|-------------:|--------:|
| Baseline | 1,000.6 ms | 2.48 ms | 0.14 ms |     baseline |         |
|      Bar |   150.9 ms | 1.30 ms | 0.07 ms | 6.63x faster |   0.00x |
|      Foo | 1,150.4 ms | 5.17 ms | 0.28 ms | 1.15x slower |   0.00x |
```

This feature was implemented in [#731](https://github.com/dotnet/BenchmarkDotNet/issues/721).

### Improved CoreRun support

BenchmarkDotNet was reporting invalid .NET Core version number when comparing performance using CoreRuns built from `dotnet/corefx` and  `dotnet/runtime`. Fixed by [@adamsitnik](https://github.com/adamsitnik) in [#1580](https://github.com/dotnet/BenchmarkDotNet/pull/1580)

In [#1552](https://github.com/dotnet/BenchmarkDotNet/pull/1552) [@stanciuadrian](https://github.com/stanciuadrian) has implemented support for all `GcMode` characteristics for `CoreRunToolchain`. Previously the settings were just ignored, now they are being translated to corresponding `COMPlus_*` env vars.

### Improved CoreRT support

CoreRT has moved from https://github.com/dotnet/corert/ to https://github.com/dotnet/runtimelab/tree/feature/NativeAOT and we had to update the default compiler version and nuget feed address. Moreover, there was a bug in `CoreRtToolchain` which was causing any additional native dependencies to not work.

Big thanks to [@MichalStrehovsky](https://github.com/MichalStrehovsky), [@jkotas](https://github.com/jkotas) and [@kant2002](https://github.com/kant2002) for their help and support!

[#1606](https://github.com/dotnet/BenchmarkDotNet/pull/1606), [#1643](https://github.com/dotnet/BenchmarkDotNet/pull/1643), [#1679](https://github.com/dotnet/BenchmarkDotNet/pull/1679)

### Command-line argument support in BenchmarkRunner

So far only `BenchmarkSwitcher` was capable of handling console line arguments. Thanks to [@chan18](https://github.com/chan18) `BenchmarkRunner` supports them as well ([#1292](https://github.com/dotnet/BenchmarkDotNet/pull/1292)):

```cs
public class Program
{
    public static void Main(string[] args) => BenchmarkRunner.Run(typeof(Program).Assembly, args: args); 
}
```

### New API: ManualConfig.CreateMinimumViable

`ManualConfig.CreateEmpty` creates a completely empty config. Without adding a column provider and a logger to the config the users won't see any results being printed. In [#1582](https://github.com/dotnet/BenchmarkDotNet/pull/1582) [@adamsitnik](https://github.com/adamsitnik) has introduced a new method that creates minimum viable config:

```cs
IConfig before = ManualConfig.CreateEmpty()
    .AddColumnProvider(DefaultColumnProviders.Instance)
    .AddLogger(ConsoleLogger.Default);

IConfig after = ManualConfig.CreateMinimumViable();
```

### Benchmarking NuGet packages from custom feeds

In [#1659](https://github.com/dotnet/BenchmarkDotNet/pull/1659/) [@workgroupengineering](https://github.com/workgroupengineering) added the possibility to indicate the source of the tested nuget package and whether it is a pre-release version.

### Deterministic benchmark builds

BenchmarkDotNet is now always enforcing Deterministic builds ([#1489](https://github.com/dotnet/BenchmarkDotNet/pull/1489)) and Optimizations enabled ([#1494](https://github.com/dotnet/BenchmarkDotNet/pull/1494)) which is a must-have if you are using custom build configurations. MSBuild enforces optimizations **only** for configurations that are named `Release` (the comparison is case-insensitive).

```xml
<ItemGroup Condition=" '$(Configuration)' == 'X' ">
   <PackageReference Include="SomeLibThatYouWantToBenchmark" Version="1.0.0" />
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Y' ">
   <PackageReference Include="SomeLibThatYouWantToBenchmark" Version="2.0.0" />
</ItemGroup>
```

```cs
var config = DefaultConfig.Instance
  .AddJob(Job.Default.WithCustomBuildConfiguration("X").WithId("X").AsBaseline())
  .AddJob(Job.Default.WithCustomBuildConfiguration("Y").WithId("Y"));
```

[#1489](https://github.com/dotnet/BenchmarkDotNet/pull/1489), [#1494](https://github.com/dotnet/BenchmarkDotNet/pull/1494)

### Improved Hardware Counters support

BenchmarkDotNet is being used by the .NET Team to ensure that .NET is not regressing. More than three thousand benchmarks (they can be found [here](https://github.com/dotnet/performance/tree/main/src/benchmarks/micro)) are being executed multiple times a day on multiple hardware configs. Recently, .NET Team started to use `InstructionsRetired` to help to filter unstable benchmarks that report regressions despite not changing the number of instructions retired. This has exposed few bugs in Hardware Counters support in BenchmarkDotNet, which all got fixed by [@adamsitnik](https://github.com/adamsitnik) in [#1547](https://github.com/dotnet/BenchmarkDotNet/pull/1547) and [#1550](https://github.com/dotnet/BenchmarkDotNet/pull/1550). Moreover, we have **removed** the old [PmcDiagnoser](https://adamsitnik.com/Hardware-Counters-Diagnoser/) and extended [EtwProfiler](https://adamsitnik.com/ETW-Profiler/) with the hardware counters support. It's just much more accurate and futureproof. For details, please go to [#1548](https://github.com/dotnet/BenchmarkDotNet/pull/1548).

How stable was `PmcDiagnoser` (same benchmarks run twice in a row on the same machine):

|    Method |              Runtime | InstructionRetired/Op |
|---------- |--------------------- |----------------------:|
| Burgers_0 |             .NET 5.0 |               845,746 |
| Burgers_0 |        .NET Core 2.1 |            30,154,151 |
| Burgers_0 | .NET Framework 4.6.1 |             4,230,848 |

|    Method |              Runtime | InstructionRetired/Op |
|---------- |--------------------- |----------------------:|
| Burgers_0 |             .NET 5.0 |            34,154,524 |
| Burgers_0 |        .NET Core 2.1 |           246,534,203 |
| Burgers_0 | .NET Framework 4.6.1 |             2,607,686 |

How stable is `EtwProfiler`:

|    Method |              Runtime | InstructionRetired/Op |
|---------- |--------------------- |----------------------:|
| Burgers_0 |             .NET 5.0 |         3,069,978,261 |
| Burgers_0 |        .NET Core 2.1 |         3,676,000,000 |
| Burgers_0 | .NET Framework 4.6.1 |         3,468,866,667 |

|    Method |              Runtime | InstructionRetired/Op |
|---------- |--------------------- |----------------------:|
| Burgers_0 |             .NET 5.0 |         3,066,810,000 |
| Burgers_0 |        .NET Core 2.1 |         3,674,666,667 |
| Burgers_0 | .NET Framework 4.6.1 |         3,468,600,000 |

Moreover, in [#1540](https://github.com/dotnet/BenchmarkDotNet/pull/1540) [@WojciechNagorski](https://github.com/WojciechNagorski) has added the removal of temporary files created by `EtwProfiler`.

### Improved Troubleshooting

We have the possibility to ask BDN to stop on the first error: `--stopOnFirstError true`.

The problem was when the users had not asked for that, tried to run `n` benchmarks, all of them failed to build, and BDN was printing the same build error `n` times.

In [#1672](https://github.com/dotnet/BenchmarkDotNet/pull/1672) [@adamsitnik](https://github.com/adamsitnik) has changed that, so when all the build fails, BDN stops after printing the first error.

Moreover, we have also changed the default behavior for the failed builds of the boilerplate code. If the build fails, we don't remove the files. Previously we have required the users to pass `--keepFiles` to keep them. See [#1567](https://github.com/dotnet/BenchmarkDotNet/pull/1567) for more details and don't forget about the [Troubleshooting](https://benchmarkdotnet.org/articles/guides/troubleshooting.html) docs!

### Docs and Samples improvements

Big thanks to [@lukasz-pyrzyk](https://github.com/lukasz-pyrzyk), [@fleckert](https://github.com/fleckert), [@MarecekF](https://github.com/MarecekF), [@joostas](https://github.com/joostas), [@michalgalecki](https://github.com/michalgalecki), [@WojciechNagorski](https://github.com/WojciechNagorski), [@MendelMonteiro](https://github.com/MendelMonteiro), [@kevinsalimi](https://github.com/kevinsalimi), [@cedric-cf](https://github.com/cedric-cf), [@YohDeadfall](https://github.com/YohDeadfall),  [@jeffhandley](https://github.com/jeffhandley) and [@JohannesDeml](https://github.com/JohannesDeml) who have improved our docs and samples!

[#1463](https://github.com/dotnet/BenchmarkDotNet/pull/1463), [#1465](https://github.com/dotnet/BenchmarkDotNet/pull/1465), [#1508](https://github.com/dotnet/BenchmarkDotNet/pull/1508), [#1518](https://github.com/dotnet/BenchmarkDotNet/pull/1518), [#1554](https://github.com/dotnet/BenchmarkDotNet/pull/1554), [#1568](https://github.com/dotnet/BenchmarkDotNet/pull/1568), [#1601](https://github.com/dotnet/BenchmarkDotNet/pull/1601), [#1633](https://github.com/dotnet/BenchmarkDotNet/pull/1633), [#1645](https://github.com/dotnet/BenchmarkDotNet/pull/1645), [#1647](https://github.com/dotnet/BenchmarkDotNet/pull/1647), [#1657](https://github.com/dotnet/BenchmarkDotNet/pull/1657), [#1675](https://github.com/dotnet/BenchmarkDotNet/pull/1675), [#1676](https://github.com/dotnet/BenchmarkDotNet/pull/1676), [#1690](https://github.com/dotnet/BenchmarkDotNet/pull/1690).

### Template improvements

* Projects created out of our official templates might have been unexpectedly packed when running `dotnet pack` on the entire solution. In [#1584](https://github.com/dotnet/BenchmarkDotNet/pull/1584) [@kendaleiv](https://github.com/kendaleiv) has explicitly disabled packing for the template.
* The template had `netcoreapp3.0` TFM hardcoded. This got fixed by [@https://github.com/ExceptionCaught](https://github.com/ExceptionCaught) in [#1630](https://github.com/dotnet/BenchmarkDotNet/pull/1630) and [#1632](https://github.com/dotnet/BenchmarkDotNet/pull/1632).
* In [#1667](https://github.com/dotnet/BenchmarkDotNet/pull/1667) [@YohDeadfall](https://github.com/YohDeadfall) has changed the default debug type from `portable` to `pdbonly` (required by `DisassemblyDiagnoser`).

## Bug fixes

 * Very long string `[Arguments]` and `[Params]` were causing BenchmarkDotNet to crash. Fixed by [@adamsitnik](https://github.com/adamsitnik) in [#1248](https://github.com/dotnet/BenchmarkDotNet/pull/1248) and [#1545](https://github.com/dotnet/BenchmarkDotNet/pull/1545/). So far trace file names were containing full benchmark names and arguments. Now if the name is too long, the trace file name is a hash (consistent for multiple runs of the same benchmark). The same goes for passing benchmark name by the host process to the benchmark process via command-line arguments.
* `LangVersion` set to a non-numeric value like `latest` was crashing the build. Fixed by [@martincostello](https://github.com/martincostello) in [#1420](https://github.com/dotnet/BenchmarkDotNet/pull/1420).
* Windows 10 November 201**9** was being recognized as 201**8**. Fixed by [@kapsiR](https://github.com/kapsiR) in [#1437](https://github.com/dotnet/BenchmarkDotNet/pull/1437).
* Assemblies loaded via streams were not supported. Fixed by [@jeremyosterhoudt](https://github.com/jeremyosterhoudt) in [#1443](https://github.com/dotnet/BenchmarkDotNet/pull/1443).
* [NativeMemoryProfiler](https://wojciechnagorski.com/2019/08/analyzing-native-memory-allocation-with-benchmarkdotnet/) was detecting small leaks that were false positives. Fixed by [@WojciechNagorski](https://github.com/WojciechNagorski) in [#1451](https://github.com/dotnet/BenchmarkDotNet/pull/1451) and [#1600](https://github.com/dotnet/BenchmarkDotNet/pull/1600).
* [DisassemblyDiagnoser](https://adamsitnik.com/Disassembly-Diagnoser/) was crashing on Linux. Fixed by [@damageboy](https://github.com/damageboy) in [#1459](https://github.com/dotnet/BenchmarkDotNet/pull/1459).
* Target framework moniker was being printed as toolchain name for Full .NET Framework benchmarks. Fixed by [@svick](https://github.com/svick) in [#1471](https://github.com/dotnet/BenchmarkDotNet/pull/1471).
* `[ParamsSource]` returning `IEnumerable<object[]>` was not working properly when combined with `[Arguments]`. Fixed by [@adamsitnik](https://github.com/adamsitnik) in [#1478](https://github.com/dotnet/BenchmarkDotNet/pull/1478). 
* `NullReferenceException` in `MultimodalDistributionAnalyzer`. Fixed by [@suslovk](https://github.com/suslovk) in [#1488](https://github.com/dotnet/BenchmarkDotNet/pull/1488).
* `NotSupportedException` was being thrown if there was an encoding mismatch between host and benchmark process. Diagnosed by [@ChristophLindemann](https://github.com/ChristophLindemann) in [#1487](https://github.com/dotnet/BenchmarkDotNet/issues/1487), fixed by [@lovettchris](https://github.com/lovettchris) in [#1491](https://github.com/dotnet/BenchmarkDotNet/pull/1491).
* `MissingMethodException` was being thrown in projects that referenced a newer version of [Iced](https://github.com/icedland/iced). Fixed by [@Symbai](https://github.com/Symbai) in [#1497](https://github.com/dotnet/BenchmarkDotNet/pull/1497) and in [#1502](https://github.com/dotnet/BenchmarkDotNet/pull/1502).
* `AppendTargetFrameworkToOutputPath` set to `false` was not supported. Fixed by [@adamsitnik](https://github.com/adamsitnik) in [#1563](https://github.com/dotnet/BenchmarkDotNet/pull/1563)
* A locking finalizer could have hanged benchmark process which would just print `// AfterAll` and never quit. Fixed by [@adamsitnik](https://github.com/adamsitnik) in [#1571](https://github.com/dotnet/BenchmarkDotNet/pull/1571). To prevent other hangs from happening, a timeout of `250ms` was added. If the process does not quit after running the benchmarks and waiting `250ms`, it's being force killed.
* In some cases, `JsonExporter` was reporting `NaN` for some of the Statistics. This was breaking non-.NET JSON deserializers. Fixed by [@marcnet80](https://github.com/marcnet80) in [#1581](https://github.com/dotnet/BenchmarkDotNet/pull/1581).
* `UnitType.Size` metrics were not using the provided number format. Fixed by [@jodydonetti](https://github.com/jodydonetti) in [#1569](https://github.com/dotnet/BenchmarkDotNet/pull/1569) and [#1618](https://github.com/dotnet/BenchmarkDotNet/pull/1618).
* `MaxColumnWidth` setting was not used for type names. Fixed by [@JohannesDeml](https://github.com/JohannesDeml) in [#1609](https://github.com/dotnet/BenchmarkDotNet/pull/1609).
* Current culture was not respected when formatting `Ratio` column values. Fixed by [@JohannesDeml](https://github.com/JohannesDeml) in [#1610](https://github.com/dotnet/BenchmarkDotNet/pull/1610).
* BenchmarkDotNet was redirecting Standard Error of the benchmark process, which was causing deadlocks for benchmarks that were writing to it. Fixed by [@adamstinik](https://github.com/adamsitnik) in [#1631](https://github.com/dotnet/BenchmarkDotNet/pull/1631)
* `DisassemblyDiagnoser` was failing to disassemble multiline source code. [@YohDeadfall](https://github.com/YohDeadfall) fixed that in [#1674](https://github.com/dotnet/BenchmarkDotNet/pull/1674).
* In [#1644](https://github.com/dotnet/BenchmarkDotNet/pull/1644) [@adamstinik](https://github.com/adamsitnik) has fixed the inconsistency between benchmark filter and hint.

## Removal of the dotnet global tool

In [#1006](https://github.com/dotnet/BenchmarkDotNet/pull/1006) (0.11.4) we have introduced a new dotnet global tool.

By looking at the number of reported bugs we got to the conclusion that the tool has not passed the test of time.

Why? Because it was based entirely on dynamic assembly loading which is very hard to get right in .NET and the fact that we support all existing .NET Runtimes (.NET, .NET Core, Mono, CoreRT) made it even harder (if not impossible).

**We have removed it and the old versions are no longer supported**. For more details, please refer to [#1572](https://github.com/dotnet/BenchmarkDotNet/pull/1572).