-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Add fast path to Array.ConstrainedCopy for single-dimensional arrays #122530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: jkotas <[email protected]>
|
Tagging subscribers to this area: @dotnet/area-system-runtime |
Co-authored-by: jkotas <[email protected]>
|
@EgorBot -amd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds a fast path optimization to Array.ConstrainedCopy for single-dimensional zero-based arrays, bringing it to performance parity with Array.Copy. Prior to this change, ConstrainedCopy was significantly slower than Copy in .NET 9/10 due to the lack of a fast path that skips complex validation for simple array scenarios.
Key Changes:
- Added inline fast path validation and copy logic for single-dimensional arrays in
ConstrainedCopymatching the existing pattern inArray.Copy - Added Mono-specific implementation of
ConstrainedCopythat delegates toCopyImplwith the reliability flag
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/libraries/System.Private.CoreLib/src/System/Array.cs | Adds fast path to ConstrainedCopy for single-dimensional zero-based arrays using unsafe pointer operations, matching the existing fast path pattern in Array.Copy |
| src/mono/System.Private.CoreLib/src/System/Array.Mono.cs | Adds Mono-specific ConstrainedCopy implementation that delegates to CopyImpl with reliable: true |
The implementation correctly mirrors the fast path logic from Array.Copy (lines 424-452), which is appropriate since the only semantic difference between the two methods is the reliability guarantee when falling back to the slow path. The fast path handles:
- Null checks for both arrays
- Type compatibility verification using MethodTable
- Single-dimensional array detection
- Bounds validation using unsigned arithmetic overflow protection
- Appropriate copy operation based on whether the array contains GC pointers
No issues found. The code is well-implemented, follows existing patterns, and should achieve the performance goals stated in the PR description.
|
EgorBot/runtime-utils#565 (comment) confirmed expected improvement. |
Co-authored-by: jkotas <[email protected]>
|
@EgorBot -windows_x64 -intel -arm |
|
@EgorBot -windows_x64 |
|
@EgorBot -windows_intel --envvars DOTNET_ReadyToRun:0 DOTNET_TieredCompilation:0 |
Adds a fast path optimization to
Array.ConstrainedCopyfor single-dimensional zero-based arrays, bringing it to performance parity withArray.Copy. Prior to this change,ConstrainedCopywas ~5x slower thanCopyin .NET 9/10 due to the lack of a fast path.Changes Made
CoreCLR Implementation
Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length, bool reliable)that contains the fast path logic for single-dimensional zero-based arraysConstrainedCopy: Now delegates to the private helper withreliable: truefor strong exception guaranteeCopy: The publicCopy(Array, int, Array, int, int)method now delegates to the private helper withreliable: falseBuffer.BulkMoveWithWriteBarrierorSpanHelpers.Memmovefor direct copyConstrainedCopyandCopyMono Implementation
ConstrainedCopy: Implementation insrc/mono/System.Private.CoreLib/src/System/Array.Mono.csthat callsCopyImplwithreliable: truePerformance Impact
Benchmark results confirm expected improvement, bringing
Array.ConstrainedCopyto performance parity withArray.Copyfor single-dimensional arrays while maintaining the strong exception guarantee (atomicity).Testing
ConstrainedCopytests cover the functionalityThe fast path preserves the same behavior and strong exception guarantee as before, while the refactored implementation maintains a single source of truth for the optimization logic.
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.