C# 这是 ReadOnlySpan<T> 的正确用法吗?
C# is this a correct usage of ReadOnlySpan<T>?
动机:我正在开发一款软件,它应该尽可能地从它运行的机器上获得尽可能多的性能。
假设: .NET 6 中的任何 array
都可以在幕后转换为 ReadOnlySpan<T>
或其变体。
问题: 如果将 all 函数传递参数从一个 array
变成一个 ReadOnlySpan<T>
?
具体例子:
private float MethodWithArrayOfFloats(float[] arr)
{
float sum = 0;
for (var index = 0; index < arr.Length; index++)
{
sum += arr[index];
}
//What if I would have called here another method passing this array parrameter ?
return sum;
}
private float MethodWithArrayOfSpans(ReadOnlySpan<float> arr)
{
float sum = 0;
for (var index = 0; index < arr.Length; index++)
{
sum += arr[index];
}
//What if I would have called here another method passing this ReadOnlySpan parrameter ?
return sum;
}
其他观察:
- 在问这个问题之前,我已经使用 DotNetBenchmark 分析了这两种方法,并发现
ReadOnlySpan<T>
方法实际上快了大约 1ms 5_000_000 次迭代。
- Sharplab.io 上的 JIT ASM 代码生成表明第二种方法比第一种方法产生更多的指令(甚至包含一些额外的
jmp
指令)
尽管如此,这对我来说还是个谜。将此技术应用于 所有 场景是否是一个好习惯?如果不是,为什么它看起来更高效?隐藏的含义是什么?
从我的角度来看,使用 ReadOnlySpan<T>
应该最高效。由于 ReadOnlySpan<T>
是一个 ref 结构,因此存在一些限制。因此代码的可维护性降低。因此,如果您所做的是在关键解决方案的热路径上,请使用 ReadonlySpan,如果它适合并且不会使您的代码复杂化,则不使用它。
动机:我正在开发一款软件,它应该尽可能地从它运行的机器上获得尽可能多的性能。
假设: .NET 6 中的任何 array
都可以在幕后转换为 ReadOnlySpan<T>
或其变体。
问题: 如果将 all 函数传递参数从一个 array
变成一个 ReadOnlySpan<T>
?
具体例子:
private float MethodWithArrayOfFloats(float[] arr)
{
float sum = 0;
for (var index = 0; index < arr.Length; index++)
{
sum += arr[index];
}
//What if I would have called here another method passing this array parrameter ?
return sum;
}
private float MethodWithArrayOfSpans(ReadOnlySpan<float> arr)
{
float sum = 0;
for (var index = 0; index < arr.Length; index++)
{
sum += arr[index];
}
//What if I would have called here another method passing this ReadOnlySpan parrameter ?
return sum;
}
其他观察:
- 在问这个问题之前,我已经使用 DotNetBenchmark 分析了这两种方法,并发现
ReadOnlySpan<T>
方法实际上快了大约 1ms 5_000_000 次迭代。 - Sharplab.io 上的 JIT ASM 代码生成表明第二种方法比第一种方法产生更多的指令(甚至包含一些额外的
jmp
指令)
尽管如此,这对我来说还是个谜。将此技术应用于 所有 场景是否是一个好习惯?如果不是,为什么它看起来更高效?隐藏的含义是什么?
从我的角度来看,使用 ReadOnlySpan<T>
应该最高效。由于 ReadOnlySpan<T>
是一个 ref 结构,因此存在一些限制。因此代码的可维护性降低。因此,如果您所做的是在关键解决方案的热路径上,请使用 ReadonlySpan,如果它适合并且不会使您的代码复杂化,则不使用它。