Uh oh!
There was an error while loading. Please reload this page.
Go through ImmutableArray and switch manual looping to Array.Copy - #32373
Go through ImmutableArray and switch manual looping to Array.Copy#32373Therzok wants to merge 7 commits into
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.
What is the break-even point for this? This will regress small sizes.
There was a problem hiding this comment.
I'll setup a benchmark for this.
There was a problem hiding this comment.
Answered in a comment below
There was a problem hiding this comment.
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.
I can definitely split these across multiple atomic PRs so we tackle each different problem individually
jkotas
commented
Feb 15, 2020
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. |
Therzok
commented
Feb 15, 2020
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 |
jkotas
commented
Feb 15, 2020
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 . |
Therzok
commented
Feb 15, 2020
I've setup some benchmarks for the behaviour. Int32 and Object results. |
Therzok
commented
Feb 15, 2020
Not sure how to test with .NET 5 though. It seems there's a small regression for small arrays of int, |
Therzok
commented
Feb 15, 2020
Added another result for small int32 arrays. Cut-off seems to be at |
Therzok
commented
Feb 15, 2020
Now I've just made myself curious of perf characteristics of: vararr=newT[Count];varsrc=items.AsSpan(start,length);vardest=newSpan<T>(arr,offset);src.CopyTo(dest); |
…on, which is more optimized on .NET5
Therzok
commented
Feb 15, 2020
Hah, would you look at that:
|
jkotas
commented
Feb 15, 2020
|
Uh oh!
There was an error while loading. Please reload this page.
Therzok
commented
Feb 15, 2020
Sorry for that! |
| if (items == null) | ||
| if (items == null || items.Length == 0) | ||
| { | ||
| return Create<T>(); |
There was a problem hiding this comment.
Can this just return ImmutableArray<T>.Empty?
There was a problem hiding this comment.
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.
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.