@@ -13,6 +13,9 @@ private static IEnumerable<TSource> TakeIterator<TSource>(IEnumerable<TSource> s
1313 Debug . Assert ( source is not null && ! IsEmptyArray ( source ) ) ;
1414 Debug . Assert ( count > 0 ) ;
1515
16+ if ( IsSizeOptimized )
17+ return SizeOptimizedTakeIterator ( source , count ) ;
18+
1619 return
1720 source is Iterator < TSource > iterator ? ( iterator . Take ( count ) ?? Empty < TSource > ( ) ) :
1821 source is IList < TSource > sourceList ? new IListSkipTakeIterator < TSource > ( sourceList , 0 , count - 1 ) :
@@ -24,6 +27,9 @@ private static IEnumerable<TSource> TakeRangeIterator<TSource>(IEnumerable<TSour
2427 Debug . Assert ( source is not null && ! IsEmptyArray ( source ) ) ;
2528 Debug . Assert ( startIndex >= 0 && startIndex < endIndex ) ;
2629
30+ if ( IsSizeOptimized )
31+ return SizeOptimizedTakeRangeIterator ( source , startIndex , endIndex ) ;
32+
2733 return
2834 source is Iterator < TSource > iterator ? TakeIteratorRange ( iterator , startIndex , endIndex ) :
2935 source is IList < TSource > sourceList ? new IListSkipTakeIterator < TSource > ( sourceList , startIndex , endIndex - 1 ) :
@@ -42,5 +48,41 @@ static IEnumerable<TSource> TakeIteratorRange(Iterator<TSource> iterator, int st
4248 return [ ] ;
4349 }
4450 }
51+
52+ private static IEnumerable < TSource > SizeOptimizedTakeIterator < TSource > ( IEnumerable < TSource > source , int count )
53+ {
54+ Debug . Assert ( count > 0 ) ;
55+
56+ foreach ( TSource element in source )
57+ {
58+ yield return element ;
59+ if ( -- count == 0 ) break ;
60+ }
61+ }
62+
63+ private static IEnumerable < TSource > SizeOptimizedTakeRangeIterator < TSource > ( IEnumerable < TSource > source , int startIndex , int endIndex )
64+ {
65+ Debug . Assert ( source is not null ) ;
66+ Debug . Assert ( startIndex >= 0 && startIndex < endIndex ) ;
67+
68+ using IEnumerator < TSource > e = source . GetEnumerator ( ) ;
69+
70+ int index = 0 ;
71+ while ( index < startIndex && e . MoveNext ( ) )
72+ {
73+ ++ index ;
74+ }
75+
76+ if ( index < startIndex )
77+ {
78+ yield break ;
79+ }
80+
81+ while ( index < endIndex && e . MoveNext ( ) )
82+ {
83+ yield return e . Current ;
84+ ++ index ;
85+ }
86+ }
4587 }
4688}
0 commit comments