Porównaj wydajność .NET Framework vs .NET Core vs .NET 5
18.03.2020 | aktual.: 18.05.2020 19:48
Microsoft obecnie skupił się już na najnowszym runtime .NET Core i NET 5. Jednakże zapewne wielu deweloperów nadal działa na starym .NET Frameworku. Czy warto migrować/przesiadać się na .NET Core? Od strony wydajnościowej - TAK i to jak najszybciej!
O mitycznym przyspieszeniu w runtime .NET Core w porównaniu do .NET Framework pisano już wiele. Oczywiście suche wynik zapewne powiedzą więcej niż tysiące słów i zachwytów. Każdy zainteresowany może wejść na GitHuba: https://github.com/djfoxer/DotNetFrameworkVsCore gdzie stworzyłem jeden wspólny test, który odpalany jest na .NET Core i .NET Framewrok. Kod jest otwarty i oparty na wpisach blogowych Microsoftu na temat wydajności w runtime.
using BenchmarkDotNet.Attributes; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Security.Cryptography; namespace djfoxer.DotNetFrameworkVsCore.Common { public class MainBenchmark { IEnumerable<int> _tenMillionToZero = Enumerable.Range(0, 10_000_000).Reverse(); byte[] _raw = new byte[100 * 1024 * 1024]; SHA256 _sha = SHA256.Create(); static string _s = "abcdefghijklmnopqrstuvwxyz"; [GlobalSetup] public void BenchmarkSetup() { for (int index = 0; index < _raw.Length; index++) _raw[index] = (byte)index; } [Benchmark] public DayOfWeek EnumParse() => (DayOfWeek)Enum.Parse(typeof(DayOfWeek), "Thursday"); [Benchmark] public int LinqOrderBySkipFirst() { return _tenMillionToZero.OrderBy(i => i).Skip(4).First(); } [Benchmark] public byte[] Sha256() { return _sha.ComputeHash(_raw); } [Benchmark] public bool StringStartsWith() { var data = false; for (int i = 0; i < 100_000_000; i++) { data = _s.StartsWith("abcdefghijklmnopqrstuvwxy-", StringComparison.Ordinal); } return data; } [Benchmark] public object Deserialize() { var books = new List<BookToSerialize>(); for (int i = 0; i < 1_00000; i++) { string id = i.ToString(); books.Add(new BookToSerialize { Name = id, Id = id }); } var formatter = new BinaryFormatter(); var mem = new MemoryStream(); formatter.Serialize(mem, books); mem.Position = 0; return formatter.Deserialize(mem); } } }
.NET Framework vs .NET Core
Na GitHubie znajdziecie wyniki testów przeprowadzone na procesorach AMD i Intel. I tu ciekawostka. .NET Core wykorzystuje w pełni możliwość kryptograficzne procesorów AMD, co pozwala na 14x przyspieszenie w obliczaniu testowego SHA256! Wszystko dzięki użyciu natywnych(!) bibliotek kryptograficznych - CNG na Windows, a OpenSSL na Unixie.
Większość testów działa od 2x do 14x szybciej na .NET Core, niż dokładnie ten sam kod odpalony na runtime .NET Framework.
Enum 2x - poprawki w Enum.Parse/TryParse
Linq 8x - optymalizacje Linq, przepisane operatory
SHA256 2x-14x - użycie natywnej kryptografii w C++ (.NET Framework nie wykorzystuje ficzerów w procesorach AMD!), CNG na Windows / OpenSSL na Unix. O tym dlaczego AMD w kryptografii jest szybsze niż Intel znajdziecie tutaj: Will AMD’s Ryzen finally bring SHA extensions to Intel’s CPUs?
String 2x-3x - poprawki wydajnościowe związane ze operacjami na stringach
Deserialize 2x-12x - szybsza deserializacja na dużych obiektach
.NET 5
Na dniach MS wydał .NET 5 preview 1. Kod na GitHubie został już uzupełniony o nowy runtime. W celu przetestowania go należy pobrać testowe wydania: Visual Studio 2019 16.6.0 preview oraz .NET 5.0 Preview 1 SDK.
Z pierwszych testów wynika, iż różnicy (wydajnościowej) pomiędzy runtime Core, a .NET 5 nie ma. Tutaj jednak Microsoft zaznaczył, iż skupił się na przyspieszeniu wydajności w wyrażeniach regularnych i niedługo ma pojawić się szczegółowy post na ten temat. Zapewne po jego publikacji kod i wykresy, jak i ten wpis, zostaną zaktualizowane.
Zapraszam do zaktualizowanej wersji wpisu: .NET Framework (4.8) vs .NET Core (3.1.x) vs .NET 5
Umarł .NET Framework, niech żyje .NET Core (oraz .NET 5) i jego wydajn...