@@ -577,6 +577,29 @@ private static R[] AppendTo<T, R>(T[] source, int sourcePos, int count, Func<T,
577
577
return appendedResults ;
578
578
}
579
579
580
+ private static R [ ] Copy < T , R > ( this T [ ] source , int sourcePos , int count , Func < T , R > map )
581
+ {
582
+ var results = new R [ count ] ;
583
+ if ( count == 1 )
584
+ results [ 0 ] = map ( source [ sourcePos ] ) ;
585
+ else
586
+ for ( int i = 0 , j = sourcePos ; i < count ; ++ i , ++ j )
587
+ results [ i ] = map ( source [ j ] ) ;
588
+ return results ;
589
+ }
590
+
591
+ private static R [ ] AppendTo < T , R > ( this T [ ] source , R [ ] results , int sourcePos , int count , Func < T , R > map )
592
+ {
593
+ var oldResultsCount = results . Length ;
594
+ Array . Resize ( ref results , oldResultsCount + count ) ;
595
+ if ( count == 1 )
596
+ results [ oldResultsCount ] = map ( source [ sourcePos ] ) ;
597
+ else
598
+ for ( int i = oldResultsCount , j = sourcePos ; i < results . Length ; ++ i , ++ j )
599
+ results [ i ] = map ( source [ j ] ) ;
600
+ return results ;
601
+ }
602
+
580
603
private static R [ ] AppendTo < S , T , R > ( T [ ] source , S state , int sourcePos , int count , Func < S , T , R > map , R [ ] results = null )
581
604
{
582
605
if ( results == null || results . Length == 0 )
@@ -813,21 +836,26 @@ public static R[] Match<T, R>(this T[] source, Func<T, bool> condition, Func<T,
813
836
R [ ] matches = null ;
814
837
var matchFound = false ;
815
838
839
+ // todo: @perf optimize it for the two dissipate slices case to allocate the result matches once, keep the track of startA, endA, startB, endB of the matches.
816
840
var i = 0 ;
817
841
for ( ; i < source . Length ; ++ i )
818
842
if ( ! ( matchFound = condition ( source [ i ] ) ) )
819
843
{
820
844
// for accumulated matched items
821
845
if ( i != 0 && i > matchStart )
822
- matches = AppendTo ( source , matchStart , i - matchStart , map , matches ) ;
846
+ matches = matches == null
847
+ ? source . Copy ( matchStart , i - matchStart , map )
848
+ : source . AppendTo ( matches , matchStart , i - matchStart , map ) ;
823
849
matchStart = i + 1 ; // guess the next match start will be after the non-matched item
824
850
}
825
851
826
852
// when last match was found but not all items are matched (hence matchStart != 0)
827
853
if ( matchFound && matchStart != 0 )
828
- return AppendTo ( source , matchStart , i - matchStart , map , matches ) ;
854
+ return matches == null
855
+ ? source . Copy ( matchStart , i - matchStart , map )
856
+ : source . AppendTo ( matches , matchStart , i - matchStart , map ) ;
829
857
830
- return matches ?? ( matchStart == 0 ? AppendTo ( source , 0 , source . Length , map ) : Empty < R > ( ) ) ;
858
+ return matches ?? ( matchStart == 0 ? source . Copy ( 0 , source . Length , map ) : Empty < R > ( ) ) ;
831
859
}
832
860
833
861
/// <summary>Match with the additional state to use in <paramref name="condition"/> and <paramref name="map"/>
0 commit comments