@@ -11,14 +11,14 @@ Introduce `IRefStructEnumerable` to improve performance when element are fat str
1111---
1212- [ Installation] ( #Installation )
1313- [ Usage] ( #Usage )
14- - [ IRefStructEnumerable] ( #IRefStructEnumerable )
1514- [ Performances] ( #Performances )
1615- [ Features] ( #Features )
1716 - [ BCL bindings] ( #BCL )
1817 - [ Transformers] ( #Transformers )
1918 - [ Converters] ( #Converters )
2019 - [ LINQ Extensions] ( #LINQ-Extensions )
2120 - [ Other Extensions] ( #Other-Extensions )
21+ - [ IRefStructEnumerable] ( #IRefStructEnumerable )
2222---
2323
2424## Installation
@@ -52,26 +52,6 @@ int result = array
5252` x=>x ` is used to avoid boxing (and allocation) and to help generic type parameters inference.
5353You can also improve performance by using struct for Where predicate and select function.
5454
55- ## IRefStructEnumerable
56-
57- ``` csharp
58- public interface IRefStructEnumerable <out T , out TEnumerator >
59- where TEnumerator : struct , IRefStructEnumerator <T >
60- {
61- TEnumerator GetEnumerator ();
62- }
63-
64- public interface IRefStructEnumerator <T >
65- {
66- bool MoveNext ();
67-
68- void Reset ();
69-
70- ref T Current { get ; }
71- }
72- ```
73- ` ref Current ` allows to avoid copy. I should be very useful when ` T ` is a fat struct.
74-
7555## Performances
7656
7757All benchmark results are in [ here] ( Documents/BenchmarksResults ) .
@@ -114,27 +94,27 @@ For example following linq sequence:
11494
11595``` ini
11696
117- BenchmarkDotNet =v0.12.0 , OS =Windows 10.0.19041
118- Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
119- .NET Core SDK =3.1.402
120- [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105 , CoreFX 4.700.20.41903 ), X64 RyuJIT
121- DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105 , CoreFX 4.700.20.41903 ), X64 RyuJIT
97+ BenchmarkDotNet =v0.12.1 , OS =Windows 10.0.19042
98+ Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores
99+ .NET Core SDK =5.0.101
100+ [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516 , CoreFX 5.0.120.57516 ), X64 RyuJIT
101+ DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516 , CoreFX 5.0.120.57516 ), X64 RyuJIT
122102
123103
124104```
125- | Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated |
126- | -------------------------------- | ---------:| ---------: | ---------:| ------:| ------:| ------:| ------:| ----------:|
127- | LINQ | 78.19 us | 1.615 us | 1.432 us | 1.00 | - | - | - | 152 B |
128- | StructLinqWithDelegate | 45.97 us | 0.469 us | 0.439 us | 0.59 | - | - | - | 104 B |
129- | StructLinqWithDelegateZeroAlloc | 44.63 us | 0.411 us | 0.385 us | 0.57 | - | - | - | - |
130- | StructLinqZeroAlloc | 15.22 us | 0.031 us | 0.028 us | 0.19 | - | - | - | - |
105+ | Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated |
106+ | -------------------------------- | ---------- :| ----------: | - ---------:| ------:| ------:| ------:| ------:| ----------:|
107+ | LINQ | 65.116 μs | 0.6153 μs | 0.5756 μs | 1.00 | - | - | - | 152 B |
108+ | StructLinqWithDelegate | 26.146 μs | 0.2402 μs | 0.2247 μs | 0.40 | - | - | - | 96 B |
109+ | StructLinqWithDelegateZeroAlloc | 27.854 μs | 0.0938 μs | 0.0783 μs | 0.43 | - | - | - | - |
110+ | StructLinqZeroAlloc | 6.872 μs | 0.0155 μs | 0.0137 μs | 0.11 | - | - | - | - |
131111
132112
133113` StructLinq ` is significatively faster than default ` LINQ ` implementation.
134114
135115## Features
136116
137- Duck typing with ` foreach ` is available with zero allocation for ` IStructEnumerable ` and also with ` Foreach ` and ` ref ` for ` IRefStructEnumerable ` .
117+ Duck typing with ` foreach ` is available with zero allocation for ` IStructEnumerable ` .
138118
139119### BCL
140120
@@ -146,15 +126,11 @@ Following class have a `StructLinq` extension method for `IStructEnumerable`:
146126 - ` Hashset<T> ` (in [ ` Struct.Linq.BCL ` ] ( https://www.nuget.org/packages/StructLinq.BCL/ ) )
147127 - ` ImmutableArray<T> ` (in [ ` Struct.Linq.BCL ` ] ( https://www.nuget.org/packages/StructLinq.BCL/ ) )
148128
149- Following class have a ` StructLinq ` extension method for ` IRefStructEnumerable ` :
150- - ` T[] `
151- - ` List<T> ` (in [ ` Struct.Linq.BCL ` ] ( https://www.nuget.org/packages/StructLinq.BCL/ ) )
152-
153-
154129### Converters
155130Following converters are available for :
156131 - ` ToArray `
157132 - ` ToList ` (in [ ` Struct.Linq.BCL ` ] ( https://www.nuget.org/packages/StructLinq.BCL/ ) )
133+ - ` ToEnumerable `
158134### LINQ Extensions
159135Following extensions are available for :
160136 - ` Aggregate `
@@ -192,6 +168,65 @@ Following extensions are available for :
192168 - ` Order `
193169 - ` TryFirst `
194170
171+ ## IRefStructEnumerable
172+
173+ ``` csharp
174+ public interface IRefStructEnumerable <out T , out TEnumerator >
175+ where TEnumerator : struct , IRefStructEnumerator <T >
176+ {
177+ TEnumerator GetEnumerator ();
178+ }
179+
180+ public interface IRefStructEnumerator <T >
181+ {
182+ bool MoveNext ();
183+
184+ void Reset ();
185+
186+ ref T Current { get ; }
187+ }
188+ ```
189+ ` ref Current ` allows to avoid copy. I should be very useful when ` T ` is a fat struct.
190+
191+ Duck typing with ` foreach ` with ` ref ` is available with zero allocation for ` IRefStructEnumerable ` .
192+
193+ ### BCL
194+
195+ Following class have a ` StructLinq ` extension method for ` IRefStructEnumerable ` :
196+ - ` T[] `
197+ - ` List<T> ` (in [ ` Struct.Linq.BCL ` ] ( https://www.nuget.org/packages/StructLinq.BCL/ ) )
198+
199+ ### Converters
200+ Following converters are available for :
201+ - ` ToArray `
202+ - ` ToList ` (in [ ` Struct.Linq.BCL ` ] ( https://www.nuget.org/packages/StructLinq.BCL/ ) )
203+ - ` ToEnumerable `
204+ ### LINQ Extensions
205+ Following extensions are available for :
206+ - ` All `
207+ - ` Any `
208+ - ` Concat `
209+ - ` Contains `
210+ - ` Count `
211+ - ` Distinct `
212+ - ` ElementAt `
213+ - ` ElementAtOrDefault `
214+ - ` Except `
215+ - ` First `
216+ - ` FirstOrDefault `
217+ - ` Intersect `
218+ - ` Last `
219+ - ` Select `
220+ - ` Skip `
221+ - ` Sum `
222+ - ` Take `
223+ - ` Union `
224+ - ` Where `
225+ ### Other Extensions
226+ - ` LongCount `
227+ - ` UIntCount `
228+ - ` TryFirst `
229+
195230
196231
197232
0 commit comments