Skip to content

Commit

Permalink
Improve SeqEquals shape (#84524)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo authored Apr 17, 2023
1 parent e121d77 commit 7dbf6a5
Showing 1 changed file with 9 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1426,17 +1426,18 @@ private static void ThrowNullLowHighInclusive<T>(T? lowInclusive, T? highInclusi
public static unsafe bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>?
{
int length = span.Length;
int otherLength = other.Length;

if (RuntimeHelpers.IsBitwiseEquatable<T>())
{
return length == other.Length &&
return length == otherLength &&
SpanHelpers.SequenceEqual(
ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)),
((uint)length) * (nuint)sizeof(T)); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this api in such a case so we choose not to take the overhead of checking.
((uint)otherLength) * (nuint)sizeof(T)); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this api in such a case so we choose not to take the overhead of checking.
}

return length == other.Length && SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
return length == otherLength && SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
}

/// <summary>
Expand Down Expand Up @@ -2161,16 +2162,18 @@ public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, IndexOfAnyValues<
public static unsafe bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>?
{
int length = span.Length;
int otherLength = other.Length;

if (RuntimeHelpers.IsBitwiseEquatable<T>())
{
return length == other.Length &&
return length == otherLength &&
SpanHelpers.SequenceEqual(
ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)),
ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)),
((uint)length) * (nuint)sizeof(T)); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this API in such a case so we choose not to take the overhead of checking.
((uint)otherLength) * (nuint)sizeof(T)); // If this multiplication overflows, the Span we got overflows the entire address range. There's no happy outcome for this API in such a case so we choose not to take the overhead of checking.
}

return length == other.Length && SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
return length == otherLength && SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
}

/// <summary>
Expand Down

0 comments on commit 7dbf6a5

Please sign in to comment.