Since .NET version something we now have an implicit cast from string
-> ReadOnlySpan<char>
. This means that if a function accepts a ReadOnlySpan<char>
, we can just pass it a string and the "conversion" will happen automatically.
This implicit operator is not available in .NET Standard 2.0 nor in .NET Framework though... We are working with all three :)
Basically I have this field in my ref struct
private readonly ReadOnlySpan<char> _defaultDelimiters = new[] { ' ', ';' };
I use this field every time a function called Read()
is called. The alternative would be to remove this field and put a stackalloc
inside Read()
. But I do not know if that is wise or not
To make my .NET code compliant with .NET Standard 2.0 and Framework I could simply add .AsSpan()
calls to my strings. This is however "unnecessary" in .NET (Core) but my question is: Is it also performance wise worse? Or do the .AsSpan()
extension and the implicit operator perform the same operation behind the scenes anyway?
As you can see from the source code, the following code is executed for the
implicit
operator:The extension method does this
So effectively the exact same code. There is absolutely no difference in performance between these. (Possibly a small difference in branch prediction due to the opposite order of the conditions).
No, there is no heap allocation. A
Span
and aReadOnlySpan
areref struct
so they can't be allocated on the heap even if you tried (like boxing them), it's not allowed.Assuming the
char
array isstatic
(or astring
is coming from a constant value), probably you are already using the most efficient allocation method. It doesn't need to reserve any stack space, it can just take aSpan
off the existing array.Whereas
stackalloc
means you need to copy the data into it every time. Andstackalloc
can also have serious implications when used in a loop, often causing a stack overflow.If the
char
array is not static (eg you are feedingnew[]
straight into the initializer/constructor) then that is going to be even more inefficient. Keep the arraystatic
in a separate field, or just use a constantstring
value.