Note that most of the performance improvements come from PGO, which is enabled with following environment variables. PGO is not enabled in .NET 6 by default, but will be in .NET 7 IIRC. set DOTNET_ReadyToRun=0
set DOTNET_TieredPGO=1
set DOTNET_TC_QuickJitForLoops=1
Here are my own benchmarks from a CPU intensive application without any IO and already optimized for allocations. Application runs a task graph either serially or in parallel. .NET 5
--------------------------
| Method | Mean |
|------------ |---------:|
| RunParallel | 473.4 us |
| Run | 513.5 us |
.NET 6
--------------------------
| Method | Mean |
|------------ |---------:|
| RunParallel | 452.5 us |
| Run | 499.8 us |
.NET 6 PGO
--------------------------
| Method | Mean |
|------------ |---------:|
| RunParallel | 381.8 us |
| Run | 412.2 us |
.NET 5 - .NET 6 -> ~5%
.NET 5 - .NET 6 PGO -> ~20%
Here is what I learned from micro-optimizing a .NET application:- Use BenchmarkDotNet[0] for general measurements and Visual Studio profiler tools for detailed inspection. They help a lot. - Memory allocations matter. Using capturing lambdas, LINQ, even foreach on interfaces introduce allocations and slows down the application. You can use ClrHeapAllocationAnalyzer[1] to find these hidden allocations. - Using abstractions with interfaces and casting back to concrete types cause some overhead, though PGO will probably eliminate most of these. - Use LINQ cautiously as its variants are mostly slower than explicit coding. E.g. .Any() vs .Count == 0 - Checking Logger.IsEnabled() before calling Logger.Debug() etc. helps a lot. You can even automate this with Fody [2], but it breaks Edit&Continue and possibly .NET Hot Reload too, so it may hinder your productivity. [0] https://github.com/dotnet/BenchmarkDotNet [1] https://github.com/microsoft/RoslynClrHeapAllocationAnalyzer [2] https://github.com/jorisdebock/LoggerIsEnabled.Fody |
Is this really true for the example? To me it seems that the implementation for .Any actually uses .Count when available, see https://github.com/dotnet/runtime/blob/main/src/libraries/Sy...