-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Go through ImmutableArray and switch manual looping to Array.Copy #32373
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
Remove the only 'CreateDefensiveCopy' call and the method, and just forward to another overload
Passing explicit parameters should avoid calling GetLowerBound
| array[i] = items[start + i]; | ||
| } | ||
|
|
||
| Array.Copy(items, start, array, 0, length); |
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.
What is the break-even point for this? This will regress small sizes.
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.
I'll setup a benchmark for this.
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.
Answered in a comment below
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.
So it makes some cases slower and some faster. I think we would need to additional data to tell whether this is an improvement on average. E.g. we would need data about how this method is used by Roslyn that is a heavy user of ImmutableArrays to make sure that this won't regress Roslyn performance.
The rest of the PR looks good to me. Could you please revert this change so that we can take the rest?
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.
I can definitely split these across multiple atomic PRs so we tackle each different problem individually
|
Note that 3-argument version of System.Collections.Immutable runs on older runtimes too. So it is a interesting question whether to optimize it for latest .NET Core or for old runtimes. Ifdefs maybe the best answer. |
|
Interesting. Well, I saw the extra call happening in code and most of the other code was using the 5 argument version. Also, there's a mention of this kind of optimization here, at the Most notably for this PR is consistency. Even I imagine if |
That was the best way for .NET Core 3. It is no longer the best way for .NET 5. In current master, we should be using the fewer-argument overload of Array.Copy where possible after dotnet/coreclr#27641 . |
|
I've setup some benchmarks for the behaviour. Int32 and Object results. |
|
Not sure how to test with .NET 5 though. It seems there's a small regression for small arrays of int, |
|
Added another result for small int32 arrays. Cut-off seems to be at |
|
Now I've just made myself curious of perf characteristics of: var arr = new T[Count];
var src = items.AsSpan(start, length);
var dest = new Span<T>(arr, offset);
src.CopyTo(dest); |
…on, which is more optimized on .NET5
|
Hah, would you look at that:
|
|
|
src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray.cs
Show resolved
Hide resolved
|
Sorry for that! |
| if (items == null) | ||
| if (items == null || items.Length == 0) | ||
| { | ||
| return Create<T>(); |
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.
Can this just return ImmutableArray<T>.Empty?
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.
Yeah, I was thinking about that in the initial variant. I went for consistency, but I can change this, and if needed, all the others
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.
I think it would be a good idea to avoid the indirection via Create method.
Make the array copying consistent and use the optimized Array.Copy API in each case.