另一组有影响的更改出现在dotnet/runtime#32270中(在dotnet/runtime#31957中支持JIT)。在过去,泛型方法只维护了几个专用的字典槽,可以用于快速查找与泛型方法相关的类型;一旦这些槽用完,它就会回到一个较慢的查找表。这种限制不再存在,这些更改使快速查找槽可用于所有通用查找。
[Benchmark]
public void GenericDictionaries()
{
for (int i = 0; i < 14; i++)
GenericMethod<string>(i);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static object GenericMethod<T>(int level)
{
switch (level)
{
case 0: return typeof(T);
case 1: return typeof(List<T>);
case 2: return typeof(List<List<T>>);
case 3: return typeof(List<List<List<T>>>);
case 4: return typeof(List<List<List<List<T>>>>);
case 5: return typeof(List<List<List<List<List<T>>>>>);
case 6: return typeof(List<List<List<List<List<List<T>>>>>>);
case 7: return typeof(List<List<List<List<List<List<List<T>>>>>>>);
case 8: return typeof(List<List<List<List<List<List<List<List<T>>>>>>>>);
case 9: return typeof(List<List<List<List<List<List<List<List<List<T>>>>>>>>>);
case 10: return typeof(List<List<List<List<List<List<List<List<List<List<T>>>>>>>>>>);
case 11: return typeof(List<List<List<List<List<List<List<List<List<List<List<T>>>>>>>>>>>);
case 12: return typeof(List<List<List<List<List<List<List<List<List<List<List<List<T>>>>>>>>>>>>);
default: return typeof(List<List<List<List<List<List<List<List<List<List<List<List<List<T>>>>>>>>>>>>>);
}
}
Method
Runtime
Mean
Ratio
GenericDictionaries
.NET FW 4.8
104.33 ns
1.00
GenericDictionaries
.NET Core 3.1
76.71 ns
0.74
GenericDictionaries
.NET 5.0
51.53 ns
0.49
Text Processing
基于文本的处理是许多应用程序的基础,并且在每个版本中都花费了大量的精力来改进基础构建块,其他所有内容都构建在这些基础构建块之上。这些变化从 helpers处理单个字符的微优化一直延伸到整个文本处理库的大修。
系统。Char在NET 5中得到了一些不错的改进。例如,dotnet/coreclr#26848提高了char的性能。通过调整实现来要求更少的指令和更少的分支。改善char。IsWhiteSpace随后在一系列依赖于它的其他方法中出现,比如string.IsEmptyOrWhiteSpace和调整:
[Benchmark]
public int Trim() => " test ".AsSpan().Trim().Length;
Method
Runtime
Mean
Ratio
Code Size
Trim
.NET FW 4.8
21.694 ns
1.00
569 B
Trim
.NET Core 3.1
8.079 ns
0.37
377 B
Trim
.NET 5.0
6.556 ns
0.30
365 B
另一个很好的例子,dotnet/runtime#35194改进了char的性能。ToUpperInvariant和char。通过改进各种方法的内联性,将调用路径从公共api简化到核心功能,并进一步调整实现以确保JIT生成最佳代码,从而实现owerinvariant。
[Benchmark]
[Arguments("It's exciting to see great performance!")]
public int ToUpperInvariant(string s)
{
int sum = 0;
for (int i = 0; i < s.Length; i++)
sum += char.ToUpperInvariant(s[i]);
return sum;
}
Method
Runtime
Mean
Ratio
Code Size
ToUpperInvariant
.NET FW 4.8
208.34 ns
1.00
171 B
ToUpperInvariant
.NET Core 3.1
166.10 ns
0.80
164 B
ToUpperInvariant
.NET 5.0
69.15 ns
0.33
105 B