runtime: Span.CopyTo is 10-20% slower than Array.CopyTo
How to run the benchmarks:
git clone https://github.com/dotnet/performance.git
# if you have .NET Core 3.0 installed
dotnet run -c Release -f netcoreapp3.0 -p .\performance\src\benchmarks\micro\MicroBenchmarks.csproj --filter *CopyTo<String>*.Array *CopyTo<String>.Span --join --affinity 2
# if you don't have .NET Core 3.0 installed
py .\performance\scripts\benchmarks_ci.py -f netcoreapp3.0 --filter *CopyTo<String>*.Array *CopyTo<String>.Span --bdn-arguments="--join true --affinity 2"
| Method | Size | Mean |
|---|---|---|
| Array | 2048 | 511.1 ns |
| Span | 2048 | 609.9 ns |
Full docs for the new benchmarking workflow: https://github.com/dotnet/performance/blob/master/docs/benchmarking-workflow-corefx.md
category:cq theme:optimization skill-level:expert cost:medium
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 3
- Comments: 21 (21 by maintainers)
The jit doesn’t see
stringhere, it sees__Canon. If we inline enough we can sometimes get all this into unshared code and figure out the actual types, but not always…Contrast this against the codegen for the generic
CopyTotest:I didn’t even dump all the relevant codegen since it’s so big, but a few things immediately stand out:
Span<T>.ctor(T[])andBuffer.Memmove(__Canon&, __Canon&, ulong)aren’t being inlined into their caller.RuntimeTypeinstance from the type handle, possibly due to thearray.GetType() != typeof(T[])check at the beginning of the ctor./cc @EgorBo In case he has any suggestions.
There is no functional problem with it. If you look at what
InlinedSetCardsAfterBulkCopyHelperdoes, it casts theObject**toBYTE*orsize_t.Maybe the argument of
InlinedSetCardsAfterBulkCopyHelpershould be typedvoid*to make this less confusing.