作者 | Alex Yakunin
译者 | 弯月
出品 | CSDN(ID:CSDNnews)

一年前,我曾在 Fusion 性能测试中比较过 .NET 5 与前一个版本的性能,老实说,.NET 5 的性能提升给我留下了深刻的印象。今年也不例外:.NET 6 成为了 .NET 家族速度最快的版本。

首先,我们来看一看我运行的测试:

在这里插入图片描述

左:.NET 5 的输出;右:.NET 6 的输出

这是一个 Fusion 的“缓存”示例,使用了 EF Core 和 ASP.NET Core。你可以克隆代码库(https://github.com/servicetitan/Stl.Fusion.Samples),然后运行 Run-Sample-Caching.cmd 或Run-Sample-Caching-Net50.cmd。

除此之外,本文提到的所有 .NET 6.0 测试都是在启用 PGO 的情况下运行的:

set DOTNET_ReadyToRun=0set DOTNET_TieredPGO=1set DOTNET_TC_QuickJitForLoops=1

测试梗概:

  • 测试每秒会产生 2千万+ 次操作,主要是受 Fusion 的逻辑 Castle.DynamicProxy 的约束,简单来说,该测试主要是一个缓存键计算和查找逻辑。几乎每次迭代都以缓存命中结束。

  • 测试每秒产生的操作次数 <100 万次,主要是受 EF 和 SQL Server 或 ASP.NET Core 的约束。

最后的测试结果为:

  • 缓存/紧密循环的测试速度提高了 30%。
  • 测试4(向常规 Web API 添加 Fusion 缓存)在使用 .NET 6 后速度提高了 15%。
  • 常见的 HTTP 流水线测试(HttpClient 命中 ASP.NET Core 控制器,后者托管了 CRUD 风格的 EF Core 服务)的速度提高了约 4.5%。

Fusion测试套件中的性能测试也得出了相同的结果:

在这里插入图片描述
你可以克隆这些测试(https://github.com/servicetitan/Stl.Fusion),然后运行如下命令:


dotnet build -c ReleaseRun-PerformanceTest.cmd net6.0Run-PerformanceTest.cmd net5.0Run-PerformanceTest.cmd netcoreapp3.1

上方的测试集与下方的测试集完全相同,唯一的区别是前者依赖于 Fusion 的计算服务而不是常规的计算服务,也就是说它非常依赖 Fusion 的透明缓存逻辑。

详细来说:

  • 上方的测试主要计算缓存键、散列、获取异步锁,并运行 ConcurrentDictionary 查找。
  • 下方的测试会运行SQL 命令,大部分是运行 SELECT -s 获取单行数据。

很明显,在第一种情况下,.NET 6 中的 PGO 大放异彩,因此进程内缓存会为 .NET 6 带来更多优势。

至于第二类测试,由于这些测试的运行速度受到外部服务(PostgreSQL 或 SQL Server)的制约,因此 5% 的速度提升也着实不错了。InMemory EF Core 提供程序(也是一个 .NET 库)的基准测试也证实了这一点:速度提升为 14%~15%。

总结

启用 PGO后,.NET 6可以带来显著的速度提升:

  • 对于紧密循环和缓存友好的逻辑,速度提升为 30%~40%。
  • 对于不依赖于网络和IO 的代码,速度提升约为 15%。
  • 对于主要依赖于网络和IO 的常见 Web 服务,速度提升约为 5%。

我曾比较过 C# 和 C++ 上的 SIMD 加速逻辑,我打算使用相同的代码再比较一下 .NET 6。不过,很明显 .NET 6 确实是迄今为止最快的 .NET,非常感谢相关开发人员的付出!

参考链接:

  • https://alexyakunin.medium.com/net-6-vs-net-5-up-to-40-speedup-ceca9112d298
Logo

20年前,《新程序员》创刊时,我们的心愿是全面关注程序员成长,中国将拥有新一代世界级的程序员。20年后的今天,我们有了新的使命:助力中国IT技术人成长,成就一亿技术人!

更多推荐