2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System . Collections . Generic ;
5
+ using System . Numerics ;
6
+ using System . Runtime . CompilerServices ;
7
+ using System . Runtime . InteropServices ;
5
8
6
9
namespace System . Linq
7
10
{
@@ -16,15 +19,17 @@ public override IEnumerable<TResult> Select<TResult>(Func<int, TResult> selector
16
19
17
20
public int [ ] ToArray ( )
18
21
{
19
- int [ ] array = new int [ _end - _start ] ;
20
- Fill ( array , _start ) ;
22
+ int start = _start ;
23
+ int [ ] array = new int [ _end - start ] ;
24
+ Fill ( array , start ) ;
21
25
return array ;
22
26
}
23
27
24
28
public List < int > ToList ( )
25
29
{
26
- List < int > list = new List < int > ( _end - _start ) ;
27
- Fill ( SetCountAndGetSpan ( list , _end - _start ) , _start ) ;
30
+ ( int start , int end ) = ( _start , _end ) ;
31
+ List < int > list = new List < int > ( end - start ) ;
32
+ Fill ( SetCountAndGetSpan ( list , end - start ) , start ) ;
28
33
return list ;
29
34
}
30
35
@@ -33,9 +38,33 @@ public void CopyTo(int[] array, int arrayIndex) =>
33
38
34
39
private static void Fill ( Span < int > destination , int value )
35
40
{
36
- for ( int i = 0 ; i < destination . Length ; i ++ , value ++ )
41
+ ref int pos = ref MemoryMarshal . GetReference ( destination ) ;
42
+ ref int end = ref Unsafe . Add ( ref pos , destination . Length ) ;
43
+
44
+ if ( Vector . IsHardwareAccelerated &&
45
+ Vector < int > . Count <= 8 &&
46
+ destination . Length >= Vector < int > . Count )
47
+ {
48
+ Vector < int > init = new Vector < int > ( ( ReadOnlySpan < int > ) new int [ ] { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 } ) ;
49
+ Vector < int > current = new Vector < int > ( value ) + init ;
50
+ Vector < int > increment = new Vector < int > ( Vector < int > . Count ) ;
51
+
52
+ ref int oneVectorFromEnd = ref Unsafe . Subtract ( ref end , Vector < int > . Count ) ;
53
+ do
54
+ {
55
+ current . StoreUnsafe ( ref pos ) ;
56
+ current += increment ;
57
+ pos = ref Unsafe . Add ( ref pos , Vector < int > . Count ) ;
58
+ }
59
+ while ( ! Unsafe . IsAddressGreaterThan ( ref pos , ref oneVectorFromEnd ) ) ;
60
+
61
+ value = current [ 0 ] ;
62
+ }
63
+
64
+ while ( Unsafe . IsAddressLessThan ( ref pos , ref end ) )
37
65
{
38
- destination [ i ] = value ;
66
+ pos = value ++ ;
67
+ pos = ref Unsafe . Add ( ref pos , 1 ) ;
39
68
}
40
69
}
41
70
0 commit comments