-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Conversation
I'll submit the corefx PR part soon |
@AndyAyersMS could you please look at these change specifically the one in Spans? I have some changes in the span indexer which take Range. Thanks. |
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.
Left you some suggestions about re-expressing some of the C# to help the jit.
Any time you access a Range
's Start
or End
more than once you should copy it to a local Index
and refer to that instead. The jit can't do this for you today -- though maybe soon with #22255?
Even with carefully crafted C# there will still be perf issues with Range
because it ends up being passed by value on x64 and its fields can't be promoted/enregistered by the jit. Details in #22079.
And perf issues with even locally constructed and obviously from-start or from-end Index
es because the JIT doesn't see the NOT (~
) operator very often. See #22130.
src/System.Private.CoreLib/shared/System/String.Manipulation.cs
Outdated
Show resolved
Hide resolved
/// </summary> | ||
public static T[] GetArrayRange<T>(T[] array, Range range) | ||
{ | ||
return array.AsSpan(range).ToArray(); |
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.
For covariant arrays, this implementation can throw ArrayTypeMismatchException and/or return array of a different type that what it started with. Is this what we want?
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.
No, looks this is wrong implementation then. what should I use to ensure returning the exact array type?
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.
Maybe something like:
Type elementType = array.GetType().GetElementType();
Span<T> source = array.AsSpan(range);
if (elementType.IsValueType)
{
return source.ToArray();
}
else
{
T[] newArray = (T[])Array.CreateInstance(elementType, source.Length);
source.CopyTo(newArray);
return newArray;
}
I realize I've already shared my opinion on this, but I'll just note here again how I think it's unfortunate we're exposing this. Such a perf trap.
int[] array = …;
Span<int> span = array[1..3];
is going to invoke all that above goo. It'll be even worse for all those folks that love using var
everywhere:
var data = GetData();
Span<int> span = data[1..3];
Fast or slow? Who knows.
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 realize I've already shared my opinion on this, but I'll just note here again how I think it's unfortunate we're exposing this
+100
I believe that we would get much better feedback about the design if we did not add these API first and wait for feedback on why there are actually needed and what they are going to use for.
Mentioned it in dotnet/designs#48 (comment) , but got no response.
src/System.Private.CoreLib/shared/System/MemoryExtensions.Fast.cs
Outdated
Show resolved
Hide resolved
src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
Outdated
Show resolved
Hide resolved
I believe I have addressed all feedback here, anyone has more comments? |
@stephentoub @jkotas do you have any more feedback? or you are ok to merge? |
If we are going to add the super-slow indexers, I would like to see a plan for how we are going to collect feedback about their usability. |
I follow up with that with different parties. I want to ask if your request should block this PR? |
My intention was to blog about the BCL feature in the preview 3 timeline, calling out the overall design points with an explicit ask for feedback with the intent to break the API post preview 3 if that's what's needed to address the feedback. |
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Do you guys plan on also updating the version in corefx (https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/Index.cs)? I'm currently porting the Index and Range types to Mono and am unsure which version of them I should use. |
yes we have the PR dotnet/corefx#35003 but just waiting the PR porting coreclr get opened. |
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com> (cherry picked from commit b0b1617)
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com> (cherry picked from commit b0b1617)
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
* Remove old use of signing package used to work around SPC signing now that arcade has bubbled up the version. * Move dependency update for CoreFX and Core-setup dependencies to BAR/Darc/Maestro++ flow * Update property references in tests. * Version bump for CoreFX and Core-Setup dependencies. * Update test Github_20958 to use revised System.Range constructor as surface area changed with #22331.
This change does two things: shrinks the required Index/Range APIs to a minimal set, and changes the new required API names to those decided in the latest CoreFX design review (CoreCLR change at dotnet/coreclr#22331).
* Index and Range updates * Address @mikedn feedback * Address Feedback * more feedback * Use Deconstruct in Range.GetOffsetAndLength * Rename GetArrayRange to GetSubArray * Temporary disable the old Corefx Range tests * Return back the TimeSpan test disabling * Fix Range jit test * Exclude the jit test * revert the changes in the jit Range test * Address Suggested Feedback Commit migrated from dotnet/coreclr@fe11853
…reclr#22544) * Remove old use of signing package used to work around SPC signing now that arcade has bubbled up the version. * Move dependency update for CoreFX and Core-setup dependencies to BAR/Darc/Maestro++ flow * Update property references in tests. * Version bump for CoreFX and Core-Setup dependencies. * Update test Github_20958 to use revised System.Range constructor as surface area changed with dotnet/coreclr#22331. Commit migrated from dotnet/coreclr@ebaa5dd
The special casing of co-variant arrays was added in the original safe implementation to avoid exceptions from AsSpan (dotnet/coreclr#22331 (comment)). ArrayTypeMismatchException is no longer a concern with the new unsafe implementation. There is a subtle behavior change in the actual type for co-variant arrays of reference types. However, the new behavior matches Array.Resize and it is very unlikely for any code out there to depend on this co-variant arrays corner case.
The special casing of co-variant arrays was added in the original safe implementation to avoid exceptions from AsSpan (dotnet/coreclr#22331 (comment)). ArrayTypeMismatchException is no longer a concern with the new unsafe implementation. There is a subtle behavior change in the actual type for co-variant arrays of reference types. However, the new behavior matches Array.Resize and it is very unlikely for any code out there to depend on this co-variant arrays corner case.
This is the change reflect what has been decided in the design meetings. you can look at the notes here https://github.com/dotnet/apireviews/tree/master/2019/System.Index
Also the change reflect the list of the types uses Index and Range according to the spec https://github.com/dotnet/designs/blob/master/accepted/system-range/system-range.md#companion-apis