More imformation about running these types of benchmarks in .Net can be found here: https://benchmarkdotnet.org/articles/guides/getting-started.html
Enum.ToString()
Tests simple Enum.Tostring() performance. Long story short, .NET core is the clear winner, running ~10 times faster than .NET Framework during Enum.ToString() tests.
Method | Job | Runtime | Mean | Error | StdDev | Ratio |
---|---|---|---|---|---|---|
GetEnumToString | .NET 4.6.2 | .NET 4.6.2 | 325.84 ns | 1.954 ns | 1.732 ns | 1.00 |
GetEnumToString | .NET 4.7.2 | .NET 4.7.2 | 331.86 ns | 1.951 ns | 1.825 ns | 1.02 |
GetEnumToString | .NET 4.8 | .NET 4.8 | 329.34 ns | 1.752 ns | 1.639 ns | 1.01 |
GetEnumToString | .NET Core 2.2 | .NET Core 2.2 | 54.75 ns | 0.564 ns | 0.500 ns | 0.17 |
GetEnumToString | .NET Core 3.1 | .NET Core 3.1 | 27.27 ns | 0.172 ns | 0.144 ns | 0.08 |
GetEnumToString | .NET Core 5.0 | .NET Core 5.0 | 28.62 ns | 0.382 ns | 0.319 ns | 0.09 |
Below are the test details and definitions.
namespace PerformanceTests.Console.Tests { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; [SimpleJob(RuntimeMoniker.Net462, baseline: true)] [SimpleJob(RuntimeMoniker.Net472)] [SimpleJob(RuntimeMoniker.Net48)] [SimpleJob(RuntimeMoniker.NetCoreApp22)] [SimpleJob(RuntimeMoniker.NetCoreApp31)] [SimpleJob(RuntimeMoniker.NetCoreApp50)] [RPlotExporter] public class TestEnumToStringPerformance { [Benchmark] public string GetEnumToString() { return TestEnum.StringifyMe.ToString(); } private enum TestEnum { StringifyMe, } } }
Benchmark details:
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.778 (1909/November2018Update/19H2) Intel Core i7-4770K CPU 3.50GHz (Haswell), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.100-preview.3.20216.6 [Host] : .NET Core 5.0.0 (CoreCLR 5.0.20.21406, CoreFX 5.0.20.21406), X64 RyuJIT .NET 4.6.2 : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT .NET 4.7.2 : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT .NET 4.8 : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT .NET Core 2.2 : .NET Core 2.2.6 (CoreCLR 4.6.27817.03, CoreFX 4.6.27818.02), X64 RyuJIT .NET Core 3.1 : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT .NET Core 5.0 : .NET Core 5.0.0 (CoreCLR 5.0.20.21406, CoreFX 5.0.20.21406), X64 RyuJIT
Links to the implemenatations:
- .Net Core https://github.com/dotnet/runtime/blob/a80e6d4c69fcfa1e17e17130c144a567b23a12a9/src/libraries/System.Private.CoreLib/src/System/Enum.cs#L898
- .Net Framework https://referencesource.microsoft.com/#mscorlib/system/enum.cs,795
Exceptions
Tests the performance of throwing/catching an exception during a divide by zero operation. .NET Framework is ~3 times as fast as .NET Core when executing the code below.
Method | Job | Runtime | Mean | Error | StdDev | Ratio | RatioSD |
---|---|---|---|---|---|---|---|
TestExceptionAsControlFlow | .NET 4.6.2 | .NET 4.6.2 | 8.235 μs | 0.0787 μs | 0.0698 μs | 1.00 | 0.00 |
TestExceptionAsControlFlow | .NET 4.7.2 | .NET 4.7.2 | 8.183 μs | 0.1017 μs | 0.0849 μs | 0.99 | 0.01 |
TestExceptionAsControlFlow | .NET 4.8 | .NET 4.8 | 8.167 μs | 0.0990 μs | 0.0926 μs | 0.99 | 0.01 |
TestExceptionAsControlFlow | .NET Core 2.2 | .NET Core 2.2 | 24.234 μs | 0.1346 μs | 0.1051 μs | 2.94 | 0.03 |
TestExceptionAsControlFlow | .NET Core 3.1 | .NET Core 3.1 | 24.440 μs | 0.0984 μs | 0.0921 μs | 2.97 | 0.03 |
TestExceptionAsControlFlow | .NET Core 5.0 | .NET Core 5.0 | 25.207 μs | 0.2087 μs | 0.1953 μs | 3.06 | 0.04 |
Below are the test details and definitions.
namespace PerformanceTests.Console.Tests { using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using System; [SimpleJob(RuntimeMoniker.Net462, baseline: true)] [SimpleJob(RuntimeMoniker.Net472)] [SimpleJob(RuntimeMoniker.Net48)] [SimpleJob(RuntimeMoniker.NetCoreApp22)] [SimpleJob(RuntimeMoniker.NetCoreApp31)] [SimpleJob(RuntimeMoniker.NetCoreApp50)] [RPlotExporter] public class UsingExceptionsAsControlFlow { public int Value { get; set; } [GlobalSetup] public void Setup() { this.Value = 0; } [Benchmark] public int TestExceptionAsControlFlow() { try { return this.Value / 0; } catch (DivideByZeroException) { return 0; } } } }
Benchmark details:
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.778 (1909/November2018Update/19H2) Intel Core i7-4770K CPU 3.50GHz (Haswell), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.100-preview.3.20216.6 [Host] : .NET Core 5.0.0 (CoreCLR 5.0.20.21406, CoreFX 5.0.20.21406), X64 RyuJIT .NET 4.6.2 : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT .NET 4.7.2 : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT .NET 4.8 : .NET Framework 4.8 (4.8.4150.0), X64 RyuJIT .NET Core 2.2 : .NET Core 2.2.6 (CoreCLR 4.6.27817.03, CoreFX 4.6.27818.02), X64 RyuJIT .NET Core 3.1 : .NET Core 3.1.3 (CoreCLR 4.700.20.11803, CoreFX 4.700.20.12001), X64 RyuJIT .NET Core 5.0 : .NET Core 5.0.0 (CoreCLR 5.0.20.21406, CoreFX 5.0.20.21406), X64 RyuJIT