Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Fix #14961 and tweak perf in ImmutableArray #15296

Merged
merged 4 commits into from
Jan 27, 2017
Merged

Conversation

jamesqo
Copy link
Contributor

@jamesqo jamesqo commented Jan 18, 2017

Follow-up for #14798 and #13158. Specializes InsertRange for arrays, uses TryCopyTo in ImmutableArray.Builder, removes some unnecessary boxing in Remove / Replace, makes exceptions consistent in SetItem / Replace / Remove, and reenables corresponding tests.

Fixes #14961, https://github.com/dotnet/corefx/issues/13695

Copy link

@AArnott AArnott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall it looks good. Just a few comments.
Thanks for the contribution.

@@ -106,6 +106,10 @@ internal static int GetCount<T>(ref IEnumerable<T> sequence)
/// </remarks>
internal static bool TryCopyTo<T>(this IEnumerable<T> sequence, T[] array, int arrayIndex)
{
Debug.Assert(sequence != null);
Debug.Assert(array != null);
Debug.Assert(arrayIndex >= 0 && arrayIndex < array.Length);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we certain this last assert is correct? I seem to recall some APIs allowing arrayIndex == array.Length when the number of elements to be copied was 0.
Also, it appears this method simply returned false when sequence was null before. Now it will throw NullReferenceException. Are we sure no callers pass a null 1st argument (perhaps as a result of an as cast that fails)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it appears this method simply returned false when sequence was null before. Now it will throw NullReferenceException. Are we sure no callers pass a null 1st argument (perhaps as a result of an as cast that fails)?

@AArnott I double-checked and there are no callers doing that.

Are we certain this last assert is correct? I seem to recall some APIs allowing arrayIndex == array.Length when the number of elements to be copied was 0.

I did that intentionally because I thought this method was only being called in scenarios where count > 0. However, I just realized I introduced a usage in this PR where count can be 0. I'll change this to <=.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a missing test case then to exercise the count==0 case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AArnott Just added one.

if (array == null)
{
throw new InvalidOperationException(SR.InvalidOperationOnDefaultArray);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you just manually inlined a method here. Why? I see you removed the method from the interface but I don't see why. You haven't avoided any boxing at this point anyway because the boxing already took place.

Copy link
Contributor Author

@jamesqo jamesqo Jan 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AArnott Interface calls are relatively expensive, and this one was in a commonly-used codepath and trivial to remove. Plus, it let us delete code. I'll see if I can post some stats on how/if this improves perf. (edit: It's actually hard for me to do so because I've run into a bunch of issues trying to build corefx ever since https://github.com/dotnet/corefx/issues/15135. If you'd really like to see perf stats though I can wait until my build issues get resolved.)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to get numbers for me. Avoiding interface dispatch sounds worthy. Thanks.

if (array == null)
{
throw new InvalidOperationException(SR.InvalidOperationOnDefaultArray);
}

// immutableArray.Array must not be null at this point, and we know it's an
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to update the comment so it discusses the array variable instead of immutableArray.Array, now that the code beneath it deals with array?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

@karelz karelz merged commit be3d8cd into dotnet:master Jan 27, 2017
@karelz
Copy link
Member

karelz commented Jan 27, 2017

Merged, @ianhays please review post-mortem if you want to ...

@jamesqo jamesqo deleted the fix.14961 branch January 27, 2017 01:09
@karelz karelz modified the milestone: 2.0.0 Feb 4, 2017
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants