.NET性能系列文章一:.NET7的性能改进

这些方法在.NET7中变得更快

.NET性能系列文章一:.NET7的性能改进

文章插图
照片来自 CHUTTERSNAP 的 Unsplash
欢迎阅读.NET性能系列的第一章 。这一系列的特点是对.NET世界中许多不同的主题进行研究、比较性能 。正如标题所说的那样,本章节在于.NET7中的性能改进 。你将看到哪种方法是实现特定功能最快的方法,以及大量的技巧和敲门,如何付出较小的代价就能最大化你代码性能 。如果你对这些主题感兴趣,那请您继续关注 。
.NET 7目前(17.10.2022)处于预览阶段,将于2022年11月发布 。通过这个新版本,微软提供了一些大的性能改进 。这篇 .NET性能系列的第一篇文章,是关于从.NET6到.NET7最值得注意的性能改进 。
LINQ最相关的改进肯定是在LINQ中,在.NET 7中dotnet社区利用LINQ中对数字数组的处理来使用Vector<T>(SIMD) 。这大大改善了一些LINQ方法性能,你可以在List<int>int[]以及其他数字集合上调用 。现在LINQ方法也能直接访问底层数组,而不是使用枚举器访问 。让我们来看看这些方法相对于.NET 6是如何表现的 。
我使用BenchmarkDotNet来比较.NET6和.NET7相同代码的性能 。
1. Min 和 Max 方法首先是LINQ方法Min()Max() 。它们被用来识别数字枚举中的最低值或最高值 。新的实现特别要求有一个先前枚举的集合作为源,因此我们必须在这个基准测试中创建一个数组 。
[Params(1000)]public int Length { get; set; }private int[] arr;[GlobalSetup]public void GlobalSetup() => arr = Enumerable.Range(0, Length).ToArray();[Benchmark]public int Min() => arr.Min();[Benchmark]public int Max() => arr.Max();在.NET 6和.NET 7上执行这些基准,在我的机器上会得出以下结果 。
方法运行时数组长度平均值比率分配Min
.NET性能系列文章一:.NET7的性能改进

文章插图
10003,494.08 ns53.2432 BMin
.NET性能系列文章一:.NET7的性能改进

文章插图
100065.64 ns1.00-Max
.NET性能系列文章一:.NET7的性能改进

文章插图
10003,025.41 ns45.9232 BMax
.NET性能系列文章一:.NET7的性能改进

文章插图
100065.93 ns1.00-
.NET性能系列文章一:.NET7的性能改进

文章插图
这里非常突出的是新的.NET7所展示的性能改进有多大 。我们可以看到与.NET 6相比,改进幅度超过4500% 。这不仅是因为在内部实现中使用了另一种类型,而且还因为不再发生额外的堆内存分配 。
2. Average 和 Sum另一个很大的改进是Average()Sum()方法 。当处理大的double集合时,这些性能优化能展现出更好的结果,这就是为什么我们要用一个double[]来测试它们 。
[Params(1000)]public int Length { get; set; }private double[] arr;[GlobalSetup]public void GlobalSetup(){var random = new Random();arr = Enumerable.Range(0, Length).Select(_ => random.NextDouble()).ToArray();}[Benchmark]public double Average() => arr.Average();[Benchmark]public double Sum() => arr.Sum();结果显示,性能显著提高了500%以上,而且同样没有了内存分配!
方法运行时数组长度平均值比率分配Average
.NET性能系列文章一:.NET7的性能改进

文章插图
10003,438.0 ns5.5032 BAverage
.NET性能系列文章一:.NET7的性能改进

文章插图
1000630.3 ns1.00-Sum
.NET性能系列文章一:.NET7的性能改进

文章插图
10003,303.8 ns5.2532 BSum

经验总结扩展阅读