summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLevi Broderick <GrabYourPitchforks@users.noreply.github.com>2018-05-07 20:50:33 -0700
committerJan Kotas <jkotas@microsoft.com>2018-05-07 20:50:33 -0700
commitba4225e5d918f2657fbbebf18be4c7323583a8cf (patch)
tree946cedd9d4d8f8ca7dbdc652cf26448b97410229
parentd7e91fc59bbc8f0ffa4aee0ac8f517abc607ca4c (diff)
downloadcoreclr-ba4225e5d918f2657fbbebf18be4c7323583a8cf.tar.gz
coreclr-ba4225e5d918f2657fbbebf18be4c7323583a8cf.tar.bz2
coreclr-ba4225e5d918f2657fbbebf18be4c7323583a8cf.zip
Speed up Array.Reverse by using ref reassignment (#17891)
* Speed up Array.Reverse by using ref reassignment * Optimize MemoryExtensions.Reverse
-rw-r--r--src/mscorlib/shared/System/MemoryExtensions.cs22
-rw-r--r--src/mscorlib/src/System/Array.cs27
2 files changed, 29 insertions, 20 deletions
diff --git a/src/mscorlib/shared/System/MemoryExtensions.cs b/src/mscorlib/shared/System/MemoryExtensions.cs
index a706b7b685..b4782dcaf0 100644
--- a/src/mscorlib/shared/System/MemoryExtensions.cs
+++ b/src/mscorlib/shared/System/MemoryExtensions.cs
@@ -771,17 +771,21 @@ namespace System
/// </summary>
public static void Reverse<T>(this Span<T> span)
{
- ref T p = ref MemoryMarshal.GetReference(span);
- int i = 0;
- int j = span.Length - 1;
- while (i < j)
+ if (span.Length <= 1)
{
- T temp = Unsafe.Add(ref p, i);
- Unsafe.Add(ref p, i) = Unsafe.Add(ref p, j);
- Unsafe.Add(ref p, j) = temp;
- i++;
- j--;
+ return;
}
+
+ ref T first = ref MemoryMarshal.GetReference(span);
+ ref T last = ref Unsafe.Add(ref Unsafe.Add(ref first, span.Length), -1);
+ do
+ {
+ T temp = first;
+ first = last;
+ last = temp;
+ first = ref Unsafe.Add(ref first, 1);
+ last = ref Unsafe.Add(ref last, -1);
+ } while (Unsafe.IsAddressLessThan(ref first, ref last));
}
/// <summary>
diff --git a/src/mscorlib/src/System/Array.cs b/src/mscorlib/src/System/Array.cs
index 28a8d040c5..d8a958d6ab 100644
--- a/src/mscorlib/src/System/Array.cs
+++ b/src/mscorlib/src/System/Array.cs
@@ -1528,6 +1528,9 @@ namespace System
if (array.Rank != 1)
ThrowHelper.ThrowRankException(ExceptionResource.Rank_MultiDimNotSupported);
+ if (length <= 1)
+ return;
+
bool r = TrySZReverse(array, index, length);
if (r)
return;
@@ -1561,7 +1564,7 @@ namespace System
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Reverse(array, 0, array.Length);
}
-
+
public static void Reverse<T>(T[] array, int index, int length)
{
if (array == null)
@@ -1573,17 +1576,19 @@ namespace System
if (array.Length - index < length)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
- ref T p = ref Unsafe.As<byte, T>(ref array.GetRawSzArrayData());
- int i = index;
- int j = index + length - 1;
- while (i < j)
+ if (length <= 1)
+ return;
+
+ ref T first = ref Unsafe.Add(ref Unsafe.As<byte, T>(ref array.GetRawSzArrayData()), index);
+ ref T last = ref Unsafe.Add(ref Unsafe.Add(ref first, length), -1);
+ do
{
- T temp = Unsafe.Add(ref p, i);
- Unsafe.Add(ref p, i) = Unsafe.Add(ref p, j);
- Unsafe.Add(ref p, j) = temp;
- i++;
- j--;
- }
+ T temp = first;
+ first = last;
+ last = temp;
+ first = ref Unsafe.Add(ref first, 1);
+ last = ref Unsafe.Add(ref last, -1);
+ } while (Unsafe.IsAddressLessThan(ref first, ref last));
}
// Sorts the elements of an array. The sort compares the elements to each