diff --git a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs index 081b330883969f..91d51da2e58582 100644 --- a/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs +++ b/src/libraries/System.Linq/src/System/Linq/OrderedEnumerable.cs @@ -339,12 +339,9 @@ private abstract class EnumerableSorter private int[] ComputeMap(TElement[] elements, int count) { ComputeKeys(elements, count); - int[] map = new int[count]; - for (int i = 0; i < map.Length; i++) - { - map[i] = i; - } + int[] map = new int[count]; + FillIncrementing(map, 0); return map; } diff --git a/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs b/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs index bde2cede4b1b9a..41d1336018bd33 100644 --- a/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs +++ b/src/libraries/System.Linq/src/System/Linq/Range.SpeedOpt.cs @@ -2,9 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; namespace System.Linq { @@ -21,7 +18,7 @@ public override int[] ToArray() { int start = _start; int[] array = new int[_end - start]; - Fill(array, start); + FillIncrementing(array, start); return array; } @@ -29,43 +26,12 @@ public override List ToList() { (int start, int end) = (_start, _end); List list = new List(end - start); - Fill(SetCountAndGetSpan(list, end - start), start); + FillIncrementing(SetCountAndGetSpan(list, end - start), start); return list; } public void CopyTo(int[] array, int arrayIndex) => - Fill(array.AsSpan(arrayIndex, _end - _start), _start); - - private static void Fill(Span destination, int value) - { - ref int pos = ref MemoryMarshal.GetReference(destination); - ref int end = ref Unsafe.Add(ref pos, destination.Length); - - if (Vector.IsHardwareAccelerated && - destination.Length >= Vector.Count) - { - Vector init = Vector.Indices; - Vector current = new Vector(value) + init; - Vector increment = new Vector(Vector.Count); - - ref int oneVectorFromEnd = ref Unsafe.Subtract(ref end, Vector.Count); - do - { - current.StoreUnsafe(ref pos); - current += increment; - pos = ref Unsafe.Add(ref pos, Vector.Count); - } - while (!Unsafe.IsAddressGreaterThan(ref pos, ref oneVectorFromEnd)); - - value = current[0]; - } - - while (Unsafe.IsAddressLessThan(ref pos, ref end)) - { - pos = value++; - pos = ref Unsafe.Add(ref pos, 1); - } - } + FillIncrementing(array.AsSpan(arrayIndex, _end - _start), _start); public override int GetCount(bool onlyIfCheap) => _end - _start; diff --git a/src/libraries/System.Linq/src/System/Linq/Range.cs b/src/libraries/System.Linq/src/System/Linq/Range.cs index f530b6fb142fda..1bf57b0e520d01 100644 --- a/src/libraries/System.Linq/src/System/Linq/Range.cs +++ b/src/libraries/System.Linq/src/System/Linq/Range.cs @@ -3,6 +3,9 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace System.Linq { @@ -71,5 +74,37 @@ public override void Dispose() _state = -1; // Don't reset current } } + + /// Fills the with incrementing numbers, starting from . + private static void FillIncrementing(Span destination, int value) + { + ref int pos = ref MemoryMarshal.GetReference(destination); + ref int end = ref Unsafe.Add(ref pos, destination.Length); + + if (Vector.IsHardwareAccelerated && + destination.Length >= Vector.Count) + { + Vector init = Vector.Indices; + Vector current = new Vector(value) + init; + Vector increment = new Vector(Vector.Count); + + ref int oneVectorFromEnd = ref Unsafe.Subtract(ref end, Vector.Count); + do + { + current.StoreUnsafe(ref pos); + current += increment; + pos = ref Unsafe.Add(ref pos, Vector.Count); + } + while (!Unsafe.IsAddressGreaterThan(ref pos, ref oneVectorFromEnd)); + + value = current[0]; + } + + while (Unsafe.IsAddressLessThan(ref pos, ref end)) + { + pos = value++; + pos = ref Unsafe.Add(ref pos, 1); + } + } } }