Optimize Array Slicing Performance #18778
Conversation
Array slicing get and set delegated to System.Array.Copy.
✅ No release notes required |
Co-authored-by: kerams <kerams@users.noreply.github.com>
|
Returning Currently, creating two empty slices results in two empty arrays without referential equality. let a = [|1;2;3|]
let b = a[1..0]
let c = a[1..0]
printfn $"{b.Length}" // 0
printfn $"{c.Length}" // 0
printfn $"{b = c}" // True
printfn $"{System.Object.ReferenceEquals(b,c)}" // FalseBy returning let b = [||]
let c = [||]
printfn $"{b.Length}" // 0
printfn $"{c.Length}" // 0
printfn $"{b = c}" // True
printfn $"{System.Object.ReferenceEquals(b,c)}" // True // this is differentThis doesn't affect non zero sized slices, so there won't be inconsistent behavior due to array mutation. If there was code dependent on a slice always returning a unique object, regardless of size, (perhaps for a lock) this change would break it. Returning |
I think it's an acceptable change. |
|
Agreed, but should it be documented somewhere? |
|
This change is fine. |
Description
Delegate array slicing to
System.Array.Copy.Fixes #18644
Benchmark Results:
The MicroPerf benchmarks that are committed aren't launching on my installed version of .NET (I don't have .NET 10 Preview 7 access)
Using benchmarks from #18644:
Before:
After:
90% performance improvement on my machine. An AVX-512 CPU would be even faster.
Tests
Existing tests already cover array slicing get/set. This PR adds an additional test to verify an array returned as a slice is unique (different object) as is the existing behavior.
Checklist