Motivation: I am working on a piece of software that should squeeze as much performance as possible from the machine it works on.
Hypothesis: Any array
in .NET 6 can be converted behind the scenes into a ReadOnlySpan<T>
or variations of it.
Question: Is there any performance benefit if you replace all function passing parameters from an array
into a ReadOnlySpan<T>
?
Concrete Example:
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;
}
Other observations:
- Prior to asking this question I have profiled both methods using DotNetBenchmark and obtained that the
ReadOnlySpan<T>
method is actually faster by about 1ms on 5_000_000 iterations. - The JIT ASM code generation on Sharplab.io shows that the second method produces more instructions than the first one (and even contains some additional
jmp
instructions)
Nonetheless, this is a mystery for me. Is this a good practice to apply this technique to all scenarios ? If not why does it seem to be more performant ? What are the hidden implications ?
CodePudding user response:
From my perspective it should be amost always more performant to use ReadOnlySpan<T>
. As ReadOnlySpan<T>
is a ref struct, there are several limitations. And thus the code gets less maintainability. So if what you do is on the hot path of a critical solution use ReadonlySpan, if not use it if it fits and does not complicate your code.