diff --git a/Documents/BenchmarksResults/ArrayOfBigStructSum.md b/Documents/BenchmarksResults/ArrayOfBigStructSum.md index 8b5846e2..a70ef908 100644 --- a/Documents/BenchmarksResults/ArrayOfBigStructSum.md +++ b/Documents/BenchmarksResults/ArrayOfBigStructSum.md @@ -6,19 +6,19 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 -Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19042 +Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +.NET Core SDK=5.0.100-preview.7.20366.6 + [Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT + DefaultJob : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|---------------------- |-----------:|---------:|---------:|------:|-------:|------:|------:|----------:| -| ForSum | 613.3 ns | 1.19 ns | 1.06 ns | 0.10 | - | - | - | - | -| SysEnumerableSum | 5,982.1 ns | 10.64 ns | 8.89 ns | 1.00 | 0.0076 | - | - | 32 B | -| StructSum | 3,675.6 ns | 56.62 ns | 52.96 ns | 0.61 | 0.0076 | - | - | 32 B | -| RefStructSum | 2,003.0 ns | 4.87 ns | 4.56 ns | 0.33 | 0.0076 | - | - | 32 B | -| ZeroAllocStructSum | 2,275.9 ns | 42.85 ns | 35.79 ns | 0.38 | - | - | - | - | -| ZeroAllocRefStructSum | 766.0 ns | 1.32 ns | 1.24 ns | 0.13 | - | - | - | - | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------------- |-----------:|---------:|----------:|------:|--------:|-------:|------:|------:|----------:| +| Handmaded | 799.6 ns | 4.87 ns | 4.55 ns | 0.14 | 0.00 | - | - | - | - | +| SysEnumerableSum | 5,861.1 ns | 34.26 ns | 28.61 ns | 1.00 | 0.00 | - | - | - | 32 B | +| StructSum | 3,253.7 ns | 30.06 ns | 28.12 ns | 0.55 | 0.01 | 0.0038 | - | - | 32 B | +| RefStructSum | 1,886.6 ns | 22.74 ns | 18.99 ns | 0.32 | 0.00 | 0.0057 | - | - | 32 B | +| ZeroAllocStructSum | 2,337.6 ns | 46.23 ns | 110.75 ns | 0.38 | 0.02 | - | - | - | - | +| ZeroAllocRefStructSum | 716.5 ns | 6.18 ns | 5.78 ns | 0.12 | 0.00 | - | - | - | - | diff --git a/Documents/BenchmarksResults/ArrayOfClassSum.md b/Documents/BenchmarksResults/ArrayOfClassSum.md index 1937846b..43227192 100644 --- a/Documents/BenchmarksResults/ArrayOfClassSum.md +++ b/Documents/BenchmarksResults/ArrayOfClassSum.md @@ -6,16 +6,17 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|----------------- |-----------:|---------:|---------:|------:|-------:|------:|------:|----------:| -| SysSum | 515.2 ns | 1.41 ns | 1.32 ns | 0.09 | - | - | - | - | -| SysEnumerableSum | 5,782.8 ns | 18.35 ns | 17.16 ns | 1.00 | 0.0076 | - | - | 48 B | -| StructSum | 1,745.9 ns | 2.49 ns | 2.33 ns | 0.30 | - | - | - | - | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|------------------- |-----------:|----------:|----------:|------:|--------:|-------:|------:|------:|----------:| +| Handmaded | 554.7 ns | 11.12 ns | 16.98 ns | 0.07 | 0.00 | - | - | - | - | +| SysEnumerableSum | 7,922.7 ns | 158.48 ns | 330.81 ns | 1.00 | 0.00 | - | - | - | 48 B | +| StructSum | 3,192.7 ns | 62.72 ns | 67.11 ns | 0.40 | 0.02 | 0.0153 | - | - | 64 B | +| StructSumZeroAlloc | 721.0 ns | 11.62 ns | 10.87 ns | 0.09 | 0.00 | - | - | - | - | diff --git a/Documents/BenchmarksResults/ArrayOfIntSum.md b/Documents/BenchmarksResults/ArrayOfIntSum.md index e7dd765c..1bdd52ee 100644 --- a/Documents/BenchmarksResults/ArrayOfIntSum.md +++ b/Documents/BenchmarksResults/ArrayOfIntSum.md @@ -6,17 +6,17 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|----------------- |-----------:|--------:|--------:|------:|-------:|------:|------:|----------:| -| SysSum | 585.0 ns | 1.34 ns | 1.26 ns | 0.14 | - | - | - | - | -| SysEnumerableSum | 4,240.8 ns | 9.10 ns | 8.06 ns | 1.00 | 0.0076 | - | - | 32 B | -| ConvertSum | 4,798.5 ns | 5.86 ns | 5.48 ns | 1.13 | 0.0076 | - | - | 32 B | -| StructSum | 589.7 ns | 1.09 ns | 1.02 ns | 0.14 | - | - | - | - | +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|-------------------- |-----------:|---------:|---------:|------:|-------:|------:|------:|----------:| +| Handmaded | 641.2 ns | 8.73 ns | 8.16 ns | 0.15 | - | - | - | - | +| LINQ | 4,257.4 ns | 83.82 ns | 99.78 ns | 1.00 | 0.0076 | - | - | 32 B | +| StructLinqZeroAlloc | 622.3 ns | 9.07 ns | 8.48 ns | 0.15 | - | - | - | - | +| StructLinq | 782.4 ns | 11.52 ns | 9.62 ns | 0.18 | 0.0076 | - | - | 32 B | diff --git a/Documents/BenchmarksResults/ArraySelectCount.md b/Documents/BenchmarksResults/ArraySelectCount.md index 9c5b938d..4cf8550c 100644 --- a/Documents/BenchmarksResults/ArraySelectCount.md +++ b/Documents/BenchmarksResults/ArraySelectCount.md @@ -7,15 +7,15 @@ ``` ini BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 -Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.101 [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | -|-------------------- |---------:|---------:|---------:|------:|------:|------:|----------:| -| Linq | 17.86 μs | 0.107 μs | 0.100 μs | - | - | - | 48 B | -| StructLinq | 13.46 μs | 0.069 μs | 0.065 μs | - | - | - | 64 B | -| StructLinqZeroAlloc | 13.37 μs | 0.055 μs | 0.049 μs | - | - | - | - | +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|-------------------- |-------------:|----------:|----------:|------:|-------:|------:|------:|----------:| +| Linq | 19,973.59 ns | 34.920 ns | 32.664 ns | 1.000 | - | - | - | 48 B | +| StructLinq | 26.10 ns | 0.376 ns | 0.352 ns | 0.001 | 0.0153 | - | - | 64 B | +| StructLinqZeroAlloc | 11.54 ns | 0.016 ns | 0.013 ns | 0.001 | - | - | - | - | diff --git a/Documents/BenchmarksResults/Contains.md b/Documents/BenchmarksResults/Contains.md index cbb8f5d2..e88328d3 100644 --- a/Documents/BenchmarksResults/Contains.md +++ b/Documents/BenchmarksResults/Contains.md @@ -6,17 +6,16 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|-------------------- |---------:|----------:|----------:|------:|-------:|------:|------:|----------:| -| Linq | 1.174 us | 0.0023 us | 0.0021 us | 1.00 | - | - | - | - | -| Array | 1.213 us | 0.0023 us | 0.0020 us | 1.03 | - | - | - | - | -| StructLinq | 2.146 us | 0.0038 us | 0.0035 us | 1.83 | 0.0076 | - | - | 32 B | -| StructLinqZeroAlloc | 2.818 us | 0.0045 us | 0.0042 us | 2.40 | - | - | - | - | +| Method | Mean | Error | StdDev | Median | Ratio | RatioSD | Code Size | Gen 0 | Gen 1 | Gen 2 | Allocated | +|-------------------- |---------:|----------:|----------:|---------:|------:|--------:|----------:|-------:|------:|------:|----------:| +| Array | 1.191 μs | 0.0142 μs | 0.0126 μs | 1.190 μs | 1.00 | 0.00 | 98 B | - | - | - | - | +| StructLinq | 2.902 μs | 0.0251 μs | 0.0209 μs | 2.896 μs | 2.44 | 0.03 | 156 B | 0.0076 | - | - | 32 B | +| StructLinqZeroAlloc | 2.923 μs | 0.0582 μs | 0.1253 μs | 2.866 μs | 2.58 | 0.13 | 236 B | - | - | - | - | diff --git a/Documents/BenchmarksResults/ListWhereSelectSum.md b/Documents/BenchmarksResults/ListWhereSelectSum.md index 0f56af73..2ae95bb9 100644 --- a/Documents/BenchmarksResults/ListWhereSelectSum.md +++ b/Documents/BenchmarksResults/ListWhereSelectSum.md @@ -14,9 +14,9 @@ Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|-------------------------------- |---------:|---------:|---------:|------:|------:|------:|------:|----------:| -| LINQ | 65.57 μs | 0.596 μs | 0.557 μs | 1.00 | - | - | - | 152 B | -| StructLinqWithDelegate | 29.12 μs | 0.101 μs | 0.095 μs | 0.44 | - | - | - | 96 B | -| StructLinqWithDelegateZeroAlloc | 33.27 μs | 0.240 μs | 0.200 μs | 0.51 | - | - | - | - | -| StructLinqZeroAlloc | 13.71 μs | 0.034 μs | 0.032 μs | 0.21 | - | - | - | - | +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|-------------------------------- |----------:|----------:|----------:|------:|------:|------:|------:|----------:| +| LINQ | 65.640 μs | 0.3483 μs | 0.3258 μs | 1.00 | - | - | - | 152 B | +| StructLinqWithDelegate | 30.502 μs | 0.1173 μs | 0.1097 μs | 0.46 | - | - | - | 96 B | +| StructLinqWithDelegateZeroAlloc | 29.441 μs | 0.1763 μs | 0.1563 μs | 0.45 | - | - | - | - | +| StructLinqZeroAlloc | 6.303 μs | 0.0241 μs | 0.0201 μs | 0.10 | - | - | - | - | diff --git a/Documents/BenchmarksResults/RangeWhereSelectSum.md b/Documents/BenchmarksResults/RangeWhereSelectSum.md index 1a2db482..6426f833 100644 --- a/Documents/BenchmarksResults/RangeWhereSelectSum.md +++ b/Documents/BenchmarksResults/RangeWhereSelectSum.md @@ -16,7 +16,7 @@ Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical ``` | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | |---------------------------------- |----------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:| -| SysSum | 6.937 μs | 0.0217 μs | 0.0170 μs | 1.00 | 0.00 | - | - | - | - | -| SysRangeWhereSelectSum | 84.396 μs | 0.6779 μs | 0.6010 μs | 12.18 | 0.11 | - | - | - | 160 B | -| ConvertWhereSelectSumWithDelegate | 72.316 μs | 0.3989 μs | 0.3732 μs | 10.43 | 0.06 | - | - | - | 40 B | -| StructRangeWhereSelectSum | 15.050 μs | 0.0400 μs | 0.0374 μs | 2.17 | 0.01 | - | - | - | - | +| SysSum | 7.019 μs | 0.0157 μs | 0.0147 μs | 1.00 | 0.00 | - | - | - | - | +| SysRangeWhereSelectSum | 83.535 μs | 0.5238 μs | 0.4900 μs | 11.90 | 0.08 | - | - | - | 160 B | +| ConvertWhereSelectSumWithDelegate | 64.815 μs | 0.2524 μs | 0.2238 μs | 9.23 | 0.03 | - | - | - | 40 B | +| StructRangeWhereSelectSum | 7.437 μs | 0.0332 μs | 0.0310 μs | 1.06 | 0.00 | - | - | - | - | diff --git a/Documents/BenchmarksResults/Sum.md b/Documents/BenchmarksResults/Sum.md index 2afaa788..39196d1f 100644 --- a/Documents/BenchmarksResults/Sum.md +++ b/Documents/BenchmarksResults/Sum.md @@ -6,18 +6,19 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | -|----------------- |----------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:| -| ForSum | 2.822 us | 0.0067 us | 0.0059 us | 1.00 | 0.00 | - | - | - | - | -| SysSum | 42.149 us | 0.0726 us | 0.0643 us | 14.94 | 0.04 | - | - | - | 40 B | -| StructSum | 2.852 us | 0.0045 us | 0.0042 us | 1.01 | 0.00 | - | - | - | - | -| StructForEachSum | 2.858 us | 0.0068 us | 0.0063 us | 1.01 | 0.00 | - | - | - | - | -| ConvertSum | 42.165 us | 0.0595 us | 0.0527 us | 14.94 | 0.03 | - | - | - | 40 B | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | Code Size | +|------------------- |----------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:|----------:| +| ForSum | 3.080 μs | 0.0561 μs | 0.0600 μs | 1.00 | 0.00 | - | - | - | - | 17 B | +| SysSum | 41.612 μs | 0.7726 μs | 0.7227 μs | 13.50 | 0.31 | - | - | - | 40 B | 445 B | +| StructSum | 5.692 μs | 0.0111 μs | 0.0104 μs | 1.85 | 0.04 | - | - | - | 24 B | 93 B | +| StructSumZeroAlloc | 3.054 μs | 0.0545 μs | 0.0510 μs | 0.99 | 0.03 | - | - | - | - | 139 B | +| StructForEachSum | 3.077 μs | 0.0591 μs | 0.0726 μs | 1.00 | 0.03 | - | - | - | - | 22 B | +| ConvertSum | 41.976 μs | 0.6487 μs | 0.5750 μs | 13.63 | 0.30 | - | - | - | 40 B | 594 B | diff --git a/Documents/BenchmarksResults/SumOnList.md b/Documents/BenchmarksResults/SumOnList.md index 30606422..7e5056ba 100644 --- a/Documents/BenchmarksResults/SumOnList.md +++ b/Documents/BenchmarksResults/SumOnList.md @@ -6,15 +6,15 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 -Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19042 +Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +.NET Core SDK=5.0.100-preview.7.20366.6 + [Host] : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT + DefaultJob : .NET Core 3.1.9 (CoreCLR 4.700.20.47201, CoreFX 4.700.20.47203), X64 RyuJIT ``` | Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | |----------- |----------:|----------:|----------:|------:|------:|------:|------:|----------:| -| Linq | 61.786 us | 0.0490 us | 0.0409 us | 1.00 | - | - | - | 40 B | -| StructLinq | 5.849 us | 0.0027 us | 0.0025 us | 0.09 | - | - | - | - | +| Linq | 70.579 us | 0.7917 us | 0.7406 us | 1.00 | - | - | - | 40 B | +| StructLinq | 5.333 us | 0.0396 us | 0.0370 us | 0.08 | - | - | - | - | diff --git a/Documents/BenchmarksResults/ToArrayOnArraySelect.md b/Documents/BenchmarksResults/ToArrayOnArraySelect.md index 8923b07c..ec1a0d38 100644 --- a/Documents/BenchmarksResults/ToArrayOnArraySelect.md +++ b/Documents/BenchmarksResults/ToArrayOnArraySelect.md @@ -7,16 +7,16 @@ ``` ini BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 -Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.101 [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | Code Size | -|----------------------- |----------:|----------:|----------:|------:|-------:|-------:|------:|----------:|----------:| -| Linq | 17.323 μs | 0.0437 μs | 0.0387 μs | 1.00 | 8.4534 | 1.0376 | - | 39.13 KB | 0.96 KB | -| StructLinq | 22.315 μs | 0.0273 μs | 0.0228 μs | 1.29 | 8.4534 | 1.0376 | - | 39.15 KB | 0.42 KB | -| StructLinqFaster | 22.256 μs | 0.0598 μs | 0.0530 μs | 1.28 | 8.4534 | 1.0376 | - | 39.12 KB | 0.58 KB | -| StructLinqWithFunction | 8.443 μs | 0.0467 μs | 0.0365 μs | 0.49 | 8.4686 | 1.0529 | - | 39.09 KB | 0.78 KB | +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | Code Size | +|----------------------- |---------:|---------:|---------:|------:|-------:|-------:|------:|----------:|----------:| +| Linq | 22.11 μs | 0.200 μs | 0.187 μs | 1.00 | 9.5215 | 0.0305 | - | 39.13 KB | 0.96 KB | +| StructLinq | 22.10 μs | 0.191 μs | 0.169 μs | 1.00 | 9.5215 | 0.0305 | - | 39.15 KB | 0.42 KB | +| StructLinqZeroAlloc | 27.75 μs | 0.144 μs | 0.135 μs | 1.26 | 9.5215 | 0.0305 | - | 39.12 KB | 0.58 KB | +| StructLinqWithFunction | 12.03 μs | 0.155 μs | 0.145 μs | 0.54 | 9.5215 | 0.0153 | - | 39.09 KB | 0.78 KB | diff --git a/Documents/BenchmarksResults/ToArrayOnArraySelectOfClass.md b/Documents/BenchmarksResults/ToArrayOnArraySelectOfClass.md index 6b51ba5e..c5c1ce91 100644 --- a/Documents/BenchmarksResults/ToArrayOnArraySelectOfClass.md +++ b/Documents/BenchmarksResults/ToArrayOnArraySelectOfClass.md @@ -7,16 +7,16 @@ ``` ini BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 -Intel Core i7-8750H CPU 2.20GHz (Coffee Lake), 1 CPU, 12 logical and 6 physical cores +Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=5.0.101 [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | Code Size | -|----------------------- |---------:|---------:|---------:|------:|-------:|-------:|------:|----------:|----------:| -| Linq | 25.31 μs | 0.106 μs | 0.094 μs | 1.00 | 8.4534 | 1.0376 | - | 39.13 KB | 0.05 KB | -| StructLinq | 25.34 μs | 0.236 μs | 0.184 μs | 1.00 | 8.4534 | 1.0376 | - | 39.15 KB | 0.44 KB | -| StructLinqFaster | 27.77 μs | 0.240 μs | 0.225 μs | 1.10 | 8.4534 | 1.0376 | - | 39.12 KB | 0.05 KB | -| StructLinqWithFunction | 10.22 μs | 0.203 μs | 0.333 μs | 0.40 | 8.4686 | 1.0529 | - | 39.09 KB | 0.78 KB | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | Code Size | +|----------------------- |---------:|---------:|---------:|------:|--------:|-------:|-------:|------:|----------:|----------:| +| Linq | 31.76 μs | 0.539 μs | 0.477 μs | 1.00 | 0.00 | 9.5215 | 1.1902 | - | 39.13 KB | 0.05 KB | +| StructLinq | 31.56 μs | 0.315 μs | 0.295 μs | 0.99 | 0.02 | 9.5215 | 1.1902 | - | 39.15 KB | 0.44 KB | +| StructLinqZeroAlloc | 34.57 μs | 0.637 μs | 0.497 μs | 1.09 | 0.02 | 9.5215 | 1.1597 | - | 39.09 KB | 0.05 KB | +| StructLinqWithFunction | 13.82 μs | 0.214 μs | 0.189 μs | 0.44 | 0.01 | 9.5215 | 1.1902 | - | 39.09 KB | 0.05 KB | diff --git a/Documents/BenchmarksResults/ToArrayOnArrayWhere.md b/Documents/BenchmarksResults/ToArrayOnArrayWhere.md index 1bd75210..073b9d63 100644 --- a/Documents/BenchmarksResults/ToArrayOnArrayWhere.md +++ b/Documents/BenchmarksResults/ToArrayOnArrayWhere.md @@ -6,16 +6,17 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|----------------- |---------:|---------:|---------:|------:|--------:|-------:|------:|----------:| -| Linq | 31.00 us | 0.177 us | 0.165 us | 1.00 | 12.6953 | 0.0610 | - | 52.19 KB | -| StructLinq | 39.03 us | 0.146 us | 0.122 us | 1.26 | 4.7607 | - | - | 19.62 KB | -| StructLinqFaster | 23.10 us | 0.063 us | 0.059 us | 0.75 | 4.7607 | - | - | 19.55 KB | +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|----------------------- |---------:|---------:|---------:|------:|--------:|------:|------:|----------:| +| Linq | 36.18 μs | 0.472 μs | 0.418 μs | 1.00 | 12.6953 | - | - | 52.19 KB | +| StructLinq | 29.66 μs | 0.151 μs | 0.141 μs | 0.82 | 4.7607 | - | - | 19.62 KB | +| StructLinqZeroAlloc | 30.95 μs | 0.115 μs | 0.108 μs | 0.86 | 4.7607 | - | - | 19.55 KB | +| StructLinqWithFunction | 15.18 μs | 0.224 μs | 0.187 μs | 0.42 | 4.7607 | - | - | 19.55 KB | diff --git a/Documents/BenchmarksResults/ToArrayOnArrayWhereOfClass.md b/Documents/BenchmarksResults/ToArrayOnArrayWhereOfClass.md index 625dcb87..a6121ed3 100644 --- a/Documents/BenchmarksResults/ToArrayOnArrayWhereOfClass.md +++ b/Documents/BenchmarksResults/ToArrayOnArrayWhereOfClass.md @@ -6,16 +6,17 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|----------------- |---------:|---------:|---------:|------:|--------:|-------:|------:|----------:| -| Linq | 58.19 us | 0.285 us | 0.267 us | 1.00 | 25.2686 | 6.2866 | - | 103.73 KB | -| StructLinq | 59.31 us | 0.107 us | 0.100 us | 1.02 | 9.5215 | 1.1597 | - | 39.15 KB | -| StructLinqFaster | 33.79 us | 0.129 us | 0.121 us | 0.58 | 9.5215 | 1.1597 | - | 39.09 KB | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|----------------------- |----------:|---------:|---------:|------:|--------:|--------:|-------:|------:|----------:| +| Linq | 88.43 μs | 0.446 μs | 0.418 μs | 1.00 | 0.00 | 25.2686 | 6.2256 | - | 103.73 KB | +| StructLinq | 137.20 μs | 2.045 μs | 1.707 μs | 1.55 | 0.02 | 9.5215 | 0.9766 | - | 39.15 KB | +| StructLinqZeroAlloc | 134.83 μs | 1.592 μs | 1.490 μs | 1.52 | 0.02 | 9.5215 | 0.9766 | - | 39.09 KB | +| StructLinqWithFunction | 108.88 μs | 1.301 μs | 1.016 μs | 1.23 | 0.01 | 9.5215 | 1.0986 | - | 39.09 KB | diff --git a/Documents/BenchmarksResults/ToListComparison.md b/Documents/BenchmarksResults/ToListComparison.md index 540a3962..a47f6b48 100644 --- a/Documents/BenchmarksResults/ToListComparison.md +++ b/Documents/BenchmarksResults/ToListComparison.md @@ -6,20 +6,22 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - Job-ILXHKQ : .NET Framework 4.8 (4.8.4220.0), X64 RyuJIT - Job-DKIKQP : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + .NET 4.8 : .NET Framework 4.8 (4.8.4250.0), X64 RyuJIT + .NET Core 3.1 : .NET Core 3.1.10 (CoreCLR 4.700.20.51601, CoreFX 4.700.20.51901), X64 RyuJIT ``` -| Method | Runtime | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | -|---------------------------- |-------------- |---------:|---------:|---------:|--------:|-------:|------:|----------:| -| AddInList | .NET 4.8 | 32.72 us | 0.088 us | 0.073 us | 31.1890 | 0.0610 | - | 128.48 KB | -| ToArrayThenNewList | .NET 4.8 | 24.67 us | 0.045 us | 0.042 us | 19.0430 | 0.0305 | - | 78.37 KB | -| ToArrayThenNewListAndLayout | .NET 4.8 | 20.83 us | 0.039 us | 0.036 us | 9.5215 | - | - | 39.19 KB | -| AddInList | .NET Core 3.1 | 24.93 us | 0.099 us | 0.093 us | 31.2195 | 0.0916 | - | 128.32 KB | -| ToArrayThenNewList | .NET Core 3.1 | 25.29 us | 0.082 us | 0.073 us | 19.0430 | 3.7842 | - | 78.2 KB | -| ToArrayThenNewListAndLayout | .NET Core 3.1 | 21.13 us | 0.100 us | 0.093 us | 9.5215 | 1.1902 | - | 39.12 KB | +| Method | Job | Runtime | Mean | Error | StdDev | Code Size | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------------------- |-------------- |-------------- |---------:|---------:|---------:|----------:|--------:|-------:|------:|----------:| +| AddInList | .NET 4.8 | .NET 4.8 | 40.57 μs | 0.794 μs | 0.779 μs | 0.54 KB | 31.1890 | 0.0610 | - | 128.48 KB | +| ToArrayThenNewList | .NET 4.8 | .NET 4.8 | 36.83 μs | 0.327 μs | 0.273 μs | 2.77 KB | 19.0430 | 0.0610 | - | 78.37 KB | +| ToArrayThenNewListAndLayout | .NET 4.8 | .NET 4.8 | 35.33 μs | 0.704 μs | 1.269 μs | 2.98 KB | 19.0430 | 3.1738 | - | 78.37 KB | +| WithVisitor | .NET 4.8 | .NET 4.8 | 24.82 μs | 0.276 μs | 0.258 μs | 1.72 KB | 9.5215 | - | - | 39.19 KB | +| AddInList | .NET Core 3.1 | .NET Core 3.1 | 35.36 μs | 0.434 μs | 0.406 μs | 0.43 KB | 31.2195 | 7.7820 | - | 128.32 KB | +| ToArrayThenNewList | .NET Core 3.1 | .NET Core 3.1 | 38.70 μs | 0.281 μs | 0.263 μs | 1.19 KB | 19.0430 | 3.7842 | - | 78.2 KB | +| ToArrayThenNewListAndLayout | .NET Core 3.1 | .NET Core 3.1 | 36.82 μs | 0.313 μs | 0.293 μs | 0.82 KB | 19.0430 | 3.1738 | - | 78.2 KB | +| WithVisitor | .NET Core 3.1 | .NET Core 3.1 | 25.79 μs | 0.159 μs | 0.141 μs | 0.77 KB | 9.5215 | 1.1902 | - | 39.12 KB | diff --git a/Documents/BenchmarksResults/ToListOnArrayWhere.md b/Documents/BenchmarksResults/ToListOnArrayWhere.md index 6b838e5a..9c1f5f9f 100644 --- a/Documents/BenchmarksResults/ToListOnArrayWhere.md +++ b/Documents/BenchmarksResults/ToListOnArrayWhere.md @@ -6,16 +6,17 @@ ### Results: ``` ini -BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041 +BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 Intel Core i7-7700 CPU 3.60GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=3.1.402 - [Host] : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT - DefaultJob : .NET Core 3.1.8 (CoreCLR 4.700.20.41105, CoreFX 4.700.20.41903), X64 RyuJIT +.NET Core SDK=5.0.101 + [Host] : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT + DefaultJob : .NET Core 5.0.1 (CoreCLR 5.0.120.57516, CoreFX 5.0.120.57516), X64 RyuJIT ``` -| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | -|----------------- |---------:|---------:|---------:|------:|--------:|-------:|------:|----------:| -| Linq | 35.54 us | 0.138 us | 0.129 us | 1.00 | 15.6860 | 0.1221 | - | 64.34 KB | -| StructLinq | 41.27 us | 0.137 us | 0.128 us | 1.16 | 4.7607 | - | - | 19.65 KB | -| StructLinqFaster | 23.34 us | 0.056 us | 0.053 us | 0.66 | 4.7607 | - | - | 19.59 KB | +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|----------------------- |---------:|---------:|---------:|------:|--------:|-------:|------:|----------:| +| Linq | 40.79 μs | 0.252 μs | 0.224 μs | 1.00 | 15.6860 | 0.1221 | - | 64.34 KB | +| StructLinq | 32.81 μs | 0.165 μs | 0.138 μs | 0.80 | 4.7607 | - | - | 19.65 KB | +| StructLinqZeroAlloc | 31.71 μs | 0.124 μs | 0.116 μs | 0.78 | 4.7607 | - | - | 19.59 KB | +| StructLinqWithFunction | 15.64 μs | 0.104 μs | 0.087 μs | 0.38 | 4.7760 | - | - | 19.59 KB | diff --git a/src/StructLinq.BCL/Dictionary/DictionaryEnumerable.cs b/src/StructLinq.BCL/Dictionary/DictionaryEnumerable.cs index fc6b55a3..d08eeefc 100644 --- a/src/StructLinq.BCL/Dictionary/DictionaryEnumerable.cs +++ b/src/StructLinq.BCL/Dictionary/DictionaryEnumerable.cs @@ -61,5 +61,22 @@ public KeyValuePair Get(int i) ref var entry = ref dictionaryLayout.Entries[start + i]; return new KeyValuePair(entry.Key, entry.Value); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor> + { + var count = Count; + var s = start; + var array = dictionaryLayout.Entries; + for (int i = 0; i < count; i++) + { + ref var input = ref array[s+i]; + if (!visitor.Visit(new KeyValuePair(input.Key, input.Value))) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq.BCL/Dictionary/DictionaryKeyEnumerable.cs b/src/StructLinq.BCL/Dictionary/DictionaryKeyEnumerable.cs index c96b1ebc..e0539206 100644 --- a/src/StructLinq.BCL/Dictionary/DictionaryKeyEnumerable.cs +++ b/src/StructLinq.BCL/Dictionary/DictionaryKeyEnumerable.cs @@ -61,5 +61,22 @@ public TKey Get(int i) ref var entry = ref dictionaryLayout.Entries[start + i]; return entry.Key; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var count = Count; + var s = start; + var array = dictionaryLayout.Entries; + for (int i = 0; i < count; i++) + { + ref var entry = ref array[s+i]; + if (!visitor.Visit(entry.Key)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq.BCL/Dictionary/DictionaryValueEnumerable.cs b/src/StructLinq.BCL/Dictionary/DictionaryValueEnumerable.cs index 172692dd..cb23ee51 100644 --- a/src/StructLinq.BCL/Dictionary/DictionaryValueEnumerable.cs +++ b/src/StructLinq.BCL/Dictionary/DictionaryValueEnumerable.cs @@ -62,5 +62,22 @@ public TValue Get(int i) return entry.Value; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var count = Count; + var s = start; + var array = dictionaryLayout.Entries; + for (int i = 0; i < count; i++) + { + ref var entry = ref array[s+i]; + if (!visitor.Visit(entry.Value)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } + } } diff --git a/src/StructLinq.BCL/Hashset/HashsetEnumerable.cs b/src/StructLinq.BCL/Hashset/HashsetEnumerable.cs index 1f02db6e..5453d1b8 100644 --- a/src/StructLinq.BCL/Hashset/HashsetEnumerable.cs +++ b/src/StructLinq.BCL/Hashset/HashsetEnumerable.cs @@ -61,5 +61,23 @@ public T Get(int i) ref var entry = ref hashsetLayout.Entries[start + i]; return entry.Value; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var count = Count; + var s = start; + var array = hashsetLayout.Entries; + for (int i = 0; i < count; i++) + { + ref var input = ref array[s+i]; + if (!visitor.Visit(input.Value)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + + } } } diff --git a/src/StructLinq.BCL/List/BCLStructEnumerable.ToList.cs b/src/StructLinq.BCL/List/BCLStructEnumerable.ToList.cs index 73282ef2..65eba4eb 100644 --- a/src/StructLinq.BCL/List/BCLStructEnumerable.ToList.cs +++ b/src/StructLinq.BCL/List/BCLStructEnumerable.ToList.cs @@ -5,22 +5,19 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using StructLinq.BCL.List; -using StructLinq.Utils.Collections; // ReSharper disable once CheckNamespace namespace StructLinq { + // ReSharper disable once InconsistentNaming + // ReSharper disable once UnusedType.Global public static partial class BCLStructEnumerable { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static List ToList(this IStructEnumerable enumerable, int capacity, ArrayPool pool) where TEnumerator : struct, IStructEnumerator { - var list = new PooledList(capacity, pool); - var enumerator = enumerable.GetEnumerator(); - PoolLists.Fill(ref list, ref enumerator); - var array = list.ToArray(); - list.Dispose(); + var array = enumerable.ToArray(capacity, pool, x => x); var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; @@ -58,12 +55,8 @@ public static List ToList( where TEnumerable : IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var list = new PooledList(capacity, pool); - var enumerator = enumerable.GetEnumerator(); - PoolLists.Fill(ref list, ref enumerator); - var array = list.ToArray(); - list.Dispose(); - var result = new List(array.Length); + var array = enumerable.ToArray(capacity, pool, x=>x); + var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; listLayout.Size = array.Length; @@ -90,7 +83,7 @@ public static List ToList( where TEnumerator : struct, ICollectionEnumerator { var array = collection.ToArray(x => x); - var result = new List(array.Length); + var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; listLayout.Size = array.Length; @@ -103,11 +96,7 @@ public static List ToList( public static List ToList(this IRefStructEnumerable enumerable, int capacity, ArrayPool pool) where TEnumerator : struct, IRefStructEnumerator { - var list = new PooledList(capacity, pool); - var enumerator = enumerable.GetEnumerator(); - PoolLists.FillRef(ref list, ref enumerator); - var array = list.ToArray(); - list.Dispose(); + var array = enumerable.ToArray(capacity, pool, x => x); var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; @@ -128,7 +117,7 @@ public static List ToList(this IRefStructCollection { var array = enumerable.ToArray(x => x); - var result = new List(array.Length); + var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; listLayout.Size = array.Length; @@ -145,12 +134,8 @@ public static List ToList( where TEnumerable : IRefStructEnumerable where TEnumerator : struct, IRefStructEnumerator { - var list = new PooledList(capacity, pool); - var enumerator = enumerable.GetEnumerator(); - PoolLists.FillRef(ref list, ref enumerator); - var array = list.ToArray(); - list.Dispose(); - var result = new List(array.Length); + var array = enumerable.ToArray(capacity, pool, x => x); + var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; listLayout.Size = array.Length; @@ -178,7 +163,7 @@ public static List ToList( where TEnumerator : struct, IRefCollectionEnumerator { var array = enumerable.ToArray(x => x); - var result = new List(array.Length); + var result = new List(); var listLayout = BCL.Unsafe.As, ListLayout>(ref result); listLayout.Items = array; listLayout.Size = array.Length; diff --git a/src/StructLinq.BCL/List/ListEnumerable.cs b/src/StructLinq.BCL/List/ListEnumerable.cs index 938a1339..a655ca1f 100644 --- a/src/StructLinq.BCL/List/ListEnumerable.cs +++ b/src/StructLinq.BCL/List/ListEnumerable.cs @@ -56,5 +56,20 @@ public T Get(int i) return layout.Items[start + i]; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var count = Count; + var s = start; + var array = layout.Items; + for (int i = 0; i < count; i++) + { + if (!visitor.Visit(array[s+i])) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } \ No newline at end of file diff --git a/src/StructLinq.Benchmark/ArrayOfBigStructSum.cs b/src/StructLinq.Benchmark/ArrayOfBigStructSum.cs index fbd8b7cf..8c4e8ebc 100644 --- a/src/StructLinq.Benchmark/ArrayOfBigStructSum.cs +++ b/src/StructLinq.Benchmark/ArrayOfBigStructSum.cs @@ -15,7 +15,7 @@ public ArrayOfBigStructSum() array = Enumerable.Range(0, Count).Select(StructContainer.Create).ToArray(); } [Benchmark] - public int ForSum() + public int Handmaded() { int sum = 0; for (int i = 0; i < Count; i++) diff --git a/src/StructLinq.Benchmark/ArrayOfClassSum.cs b/src/StructLinq.Benchmark/ArrayOfClassSum.cs index 05b62a29..b56c5349 100644 --- a/src/StructLinq.Benchmark/ArrayOfClassSum.cs +++ b/src/StructLinq.Benchmark/ArrayOfClassSum.cs @@ -15,7 +15,7 @@ public ArrayOfClassSum() array = Enumerable.Range(0, Count).Select(x => new Container(x)).ToArray(); } [Benchmark] - public int SysSum() + public int Handmaded() { int sum = 0; for (int i = 0; i < Count; i++) @@ -29,6 +29,15 @@ public int SysSum() [Benchmark] public int StructSum() + { + return array.ToStructEnumerable() + .Select(x=> x.Element) + .Sum(); + } + + + [Benchmark] + public int StructSumZeroAlloc() { var @select = new ContainerSelect(); return array.ToStructEnumerable() diff --git a/src/StructLinq.Benchmark/ArrayOfIntSum.cs b/src/StructLinq.Benchmark/ArrayOfIntSum.cs index c69e0a68..46775660 100644 --- a/src/StructLinq.Benchmark/ArrayOfIntSum.cs +++ b/src/StructLinq.Benchmark/ArrayOfIntSum.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using BenchmarkDotNet.Attributes; using Enumerable = System.Linq.Enumerable; @@ -8,7 +9,7 @@ namespace StructLinq.Benchmark public class ArrayOfIntSum { private readonly IEnumerable sysArray; - private readonly int Count = 1000; + private readonly int Count = 1_000; private readonly int[] array; public ArrayOfIntSum() { @@ -16,7 +17,7 @@ public ArrayOfIntSum() array = Enumerable.ToArray(Enumerable.Range(0, Count)); } [Benchmark] - public int SysSum() + public int Handmaded() { int sum = 0; foreach (var i in array) @@ -26,12 +27,13 @@ public int SysSum() return sum; } [Benchmark(Baseline = true)] - public int SysEnumerableSum() => Enumerable.Sum(sysArray); + public int LINQ() => sysArray.Sum(); [Benchmark] - public int ConvertSum() => sysArray.ToStructEnumerable().Sum(x=>x); + public int StructLinqZeroAlloc() => array.ToStructEnumerable().Sum(x=>x); [Benchmark] - public int StructSum() => array.ToStructEnumerable().Sum(x=>x); + public int StructLinq() => array.ToStructEnumerable().Sum(); + } } \ No newline at end of file diff --git a/src/StructLinq.Benchmark/ArraySelectCount.cs b/src/StructLinq.Benchmark/ArraySelectCount.cs index fdd59b06..86cdd3d6 100644 --- a/src/StructLinq.Benchmark/ArraySelectCount.cs +++ b/src/StructLinq.Benchmark/ArraySelectCount.cs @@ -14,7 +14,7 @@ public ArraySelectCount() array = Enumerable.Range(0, Count).ToArray(); } - [Benchmark] + [Benchmark(Baseline = true)] public int Linq() { return array.Select(x => x * 2).Count(); @@ -32,6 +32,5 @@ public int StructLinqZeroAlloc() var select = new SelectFunction(); return array.ToStructEnumerable().Select(ref select, x=> x, x=> x).Count(x=>x); } - } } diff --git a/src/StructLinq.Benchmark/Contains.cs b/src/StructLinq.Benchmark/Contains.cs index 17d7798a..2a855d6c 100644 --- a/src/StructLinq.Benchmark/Contains.cs +++ b/src/StructLinq.Benchmark/Contains.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Linq; +using System.Linq; using BenchmarkDotNet.Attributes; namespace StructLinq.Benchmark @@ -9,22 +8,14 @@ public class Contains { private const int Count = 10_000; private readonly int[] array; - private readonly IEnumerable enumerable; public Contains() { array = Enumerable.Range(0, Count).ToArray(); - enumerable = Enumerable.Range(0, Count).ToArray(); } [Benchmark(Baseline = true)] - public bool Linq() - { - return enumerable.Contains(5_000); - } - - [Benchmark] public bool Array() { return array.Contains(5_000); diff --git a/src/StructLinq.Benchmark/ImpactOfUsingOnForEach.cs b/src/StructLinq.Benchmark/ImpactOfUsingOnForEach.cs index 22fc67d9..8ace1106 100644 --- a/src/StructLinq.Benchmark/ImpactOfUsingOnForEach.cs +++ b/src/StructLinq.Benchmark/ImpactOfUsingOnForEach.cs @@ -148,6 +148,19 @@ public IEnumerator GetIEnumerator() { return new StructEnumerator>(GetEnumerator()); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } public struct ArrayStructEnumeratorWithDispose : IStructEnumerator, IDisposable diff --git a/src/StructLinq.Benchmark/Sum.cs b/src/StructLinq.Benchmark/Sum.cs index c7da9b8a..1a9bacfc 100644 --- a/src/StructLinq.Benchmark/Sum.cs +++ b/src/StructLinq.Benchmark/Sum.cs @@ -32,6 +32,12 @@ public int SysSum() [Benchmark] public int StructSum() + { + return StructEnumerable.Range(0, Count).Sum(); + } + + [Benchmark] + public int StructSumZeroAlloc() { return StructEnumerable.Range(0, Count).Sum(x=>x); } @@ -52,7 +58,6 @@ public int ConvertSum() { return Enumerable.Range(0, Count).ToStructEnumerable().Sum(x=>x); } - } public struct IntComparer : IComparer @@ -62,4 +67,4 @@ public int Compare(int x, int y) return x - y; } } -} \ No newline at end of file +} diff --git a/src/StructLinq.Benchmark/SumOnList.cs b/src/StructLinq.Benchmark/SumOnList.cs index 9fb655d9..0c6cd5a0 100644 --- a/src/StructLinq.Benchmark/SumOnList.cs +++ b/src/StructLinq.Benchmark/SumOnList.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; namespace StructLinq.Benchmark @@ -24,6 +25,6 @@ public int StructLinq() { return list.ToStructEnumerable().Sum(x => x); } - } + } \ No newline at end of file diff --git a/src/StructLinq.Benchmark/ToArrayOnArraySelect.cs b/src/StructLinq.Benchmark/ToArrayOnArraySelect.cs index b63289dd..c0aafc58 100644 --- a/src/StructLinq.Benchmark/ToArrayOnArraySelect.cs +++ b/src/StructLinq.Benchmark/ToArrayOnArraySelect.cs @@ -28,7 +28,7 @@ public int[] StructLinq() => array [Benchmark] - public int[] StructLinqFaster() => array + public int[] StructLinqZeroAlloc() => array .ToStructEnumerable() .Select(x => x * 2) .ToArray(x=>x); @@ -42,5 +42,6 @@ public int[] StructLinqWithFunction() .Select(ref @select, x=>x, x=>x) .ToArray(x=>x); } + } } diff --git a/src/StructLinq.Benchmark/ToArrayOnArraySelectOfClass.cs b/src/StructLinq.Benchmark/ToArrayOnArraySelectOfClass.cs index c0b1e568..8bf50339 100644 --- a/src/StructLinq.Benchmark/ToArrayOnArraySelectOfClass.cs +++ b/src/StructLinq.Benchmark/ToArrayOnArraySelectOfClass.cs @@ -27,9 +27,9 @@ public int[] StructLinq() => array .ToArray(); [Benchmark] - public int[] StructLinqFaster() => array + public int[] StructLinqZeroAlloc() => array .ToStructEnumerable() - .Select(x => x.Element) + .Select(x => x.Element, x=> x) .ToArray(x=>x); diff --git a/src/StructLinq.Benchmark/ToArrayOnArrayWhere.cs b/src/StructLinq.Benchmark/ToArrayOnArrayWhere.cs index 815ed3a8..399643bf 100644 --- a/src/StructLinq.Benchmark/ToArrayOnArrayWhere.cs +++ b/src/StructLinq.Benchmark/ToArrayOnArrayWhere.cs @@ -28,7 +28,14 @@ public int[] StructLinq() => array .ToArray(); [Benchmark] - public int[] StructLinqFaster() + public int[] StructLinqZeroAlloc() => array + .ToStructEnumerable() + .Where(x => (x & 1) == 0, x=>x) + .ToArray(x=>x); + + + [Benchmark] + public int[] StructLinqWithFunction() { var where = new WherePredicate(); return array diff --git a/src/StructLinq.Benchmark/ToArrayOnArrayWhereOfClass.cs b/src/StructLinq.Benchmark/ToArrayOnArrayWhereOfClass.cs index 669c86a1..c030a916 100644 --- a/src/StructLinq.Benchmark/ToArrayOnArrayWhereOfClass.cs +++ b/src/StructLinq.Benchmark/ToArrayOnArrayWhereOfClass.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; namespace StructLinq.Benchmark @@ -27,7 +28,13 @@ public Container[] StructLinq() => array .ToArray(); [Benchmark] - public Container[] StructLinqFaster() + public Container[] StructLinqZeroAlloc() => array + .ToStructEnumerable() + .Where(x => (x.Element & 1) == 0, x=>x) + .ToArray(x=>x); + + [Benchmark] + public Container[] StructLinqWithFunction() { var where = new WhereContainerPredicate(); return array @@ -39,6 +46,7 @@ public Container[] StructLinqFaster() public readonly struct WhereContainerPredicate : IFunction { + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Eval(Container element) { return (element.Element & 1) == 0; diff --git a/src/StructLinq.Benchmark/ToListComparison.cs b/src/StructLinq.Benchmark/ToListComparison.cs index 14239ad0..75932b9f 100644 --- a/src/StructLinq.Benchmark/ToListComparison.cs +++ b/src/StructLinq.Benchmark/ToListComparison.cs @@ -4,7 +4,6 @@ using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using StructLinq.BCL.List; -using StructLinq.Range; using StructLinq.Utils.Collections; namespace StructLinq.Benchmark @@ -15,18 +14,18 @@ namespace StructLinq.Benchmark [SimpleJob(RuntimeMoniker.NetCoreApp31)] public class ToListComparison { - private RangeEnumerable enumerable; + private int[] enumerable; public ToListComparison() { - enumerable = StructEnumerable.Range(0, 10_000); + enumerable = StructEnumerable.Range(0, 10_000).ToArray(); } [Benchmark] public List AddInList() { var list = new List(); - var rangeEnumerator = enumerable.GetEnumerator(); + var rangeEnumerator = enumerable.ToStructEnumerable().GetEnumerator(); FillList(list, ref rangeEnumerator); return list; } @@ -35,7 +34,7 @@ public List AddInList() public List ToArrayThenNewList() { var list = new PooledList(0, ArrayPool.Shared); - var enumerator = enumerable.GetEnumerator(); + var enumerator = enumerable.ToStructEnumerable().GetEnumerator(); PoolLists.Fill(ref list, ref enumerator); var array = list.ToArray(); list.Dispose(); @@ -46,7 +45,7 @@ public List ToArrayThenNewList() public List ToArrayThenNewListAndLayout() { var list = new PooledList(0, ArrayPool.Shared); - var enumerator = enumerable.GetEnumerator(); + var enumerator = enumerable.ToStructEnumerable().GetEnumerator(); PoolLists.Fill(ref list, ref enumerator); var array = list.ToArray(); list.Dispose(); @@ -56,6 +55,20 @@ public List ToArrayThenNewListAndLayout() return result; } + [Benchmark] + public List WithVisitor() + { + var visitor = new PooledListVisitor(0, ArrayPool.Shared); + enumerable.ToStructEnumerable().Visit(ref visitor); + var array = visitor.PooledList.ToArray(); + visitor.Dispose(); + var result = new List(); + var listLayout = Unsafe.As, ListLayout>(ref result); + listLayout.Items = array; + listLayout.Size = array.Length; + return result; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void FillList(List list, ref TEnumerator enumerator) where TEnumerator : struct, IStructEnumerator diff --git a/src/StructLinq.Benchmark/ToListOnArrayWhere.cs b/src/StructLinq.Benchmark/ToListOnArrayWhere.cs index 8de32660..5d4d0529 100644 --- a/src/StructLinq.Benchmark/ToListOnArrayWhere.cs +++ b/src/StructLinq.Benchmark/ToListOnArrayWhere.cs @@ -1,6 +1,10 @@ -using System.Collections.Generic; +using System.Buffers; +using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; +using StructLinq.BCL.List; +using StructLinq.Utils.Collections; namespace StructLinq.Benchmark { @@ -28,7 +32,14 @@ public List StructLinq() => array .ToList(); [Benchmark] - public List StructLinqFaster() + public List StructLinqZeroAlloc() => array + .ToStructEnumerable() + .Where(x => (x & 1) == 0, x=>x) + .ToList(x=>x); + + + [Benchmark] + public List StructLinqWithFunction() { var where = new WherePredicate(); return array diff --git a/src/StructLinq.Tests/AbstractCollectionTests.cs b/src/StructLinq.Tests/AbstractCollectionTests.cs index 842f2525..aab1df8c 100644 --- a/src/StructLinq.Tests/AbstractCollectionTests.cs +++ b/src/StructLinq.Tests/AbstractCollectionTests.cs @@ -100,6 +100,28 @@ public void ShouldSkipAsEnumerable(int size, int skip) Assert.Equal(expected, values); } + [Theory] + [InlineData(10, 2)] + [InlineData(7, 5)] + [InlineData(7, 0)] + [InlineData(7, 10)] + public void ShouldSkipWithVisitor(int size, int skip) + { + TStructCollection collection = Build(size); + var array = collection.ToEnumerable().ToArray(); + + var list = new List(); + var visitor = new ListVisitor(list); + + collection.Skip(skip, x => x) + .Visit(ref visitor); + + + var values = list.ToArray(); + var expected = array.Skip((int) skip).ToArray(); + + Assert.Equal(expected, values); + } [Fact] public void ShouldSkipReturnSameSequenceWhenResetIsCall() { @@ -161,6 +183,28 @@ public void ShouldTakeAsEnumerable(int size, int take) Assert.Equal(expected, values); } + [Theory] + [InlineData(10, 2)] + [InlineData(7, 5)] + [InlineData(7, 0)] + [InlineData(7, 10)] + public void ShouldTakeWithVisitor(int size, int take) + { + TStructCollection collection = Build(size); + var array = collection.ToEnumerable().ToArray(); + + var list = new List(); + var visitor = new ListVisitor(list); + + collection.Take(take, x => x) + .Visit(ref visitor); + + var values = list.ToArray(); + var expected = array.Take((int) take).ToArray(); + + Assert.Equal(expected, values); + } + [Theory] [InlineData(10, 2)] [InlineData(7, 5)] diff --git a/src/StructLinq.Tests/AbstractEnumerableTests.cs b/src/StructLinq.Tests/AbstractEnumerableTests.cs index 6f95788e..20876bfa 100644 --- a/src/StructLinq.Tests/AbstractEnumerableTests.cs +++ b/src/StructLinq.Tests/AbstractEnumerableTests.cs @@ -130,5 +130,67 @@ public void ShouldUseDuckTypingCompatibilityForForEach() } Assert.Equal(5, count); } + + [Theory] + [InlineData(0)] + [InlineData(5)] + [InlineData(10)] + public void ShouldVisitAllEnumerable(int size) + { + //Arrange + var enumerable = Build(size); + var visitor = new ListVisitor(new List()); + + //Act + var status = enumerable.Visit(ref visitor); + + //Assert + var expected = enumerable.ToEnumerable().ToArray(); + Assert.Equal(expected, visitor.List.ToArray()); + Assert.Equal(VisitStatus.EnumeratorFinished, status); + } + + [Theory] + [InlineData(5)] + [InlineData(10)] + public void ShouldVisitFirstElement(int size) + { + //Arrange + var enumerable = Build(size); + var visitor = new FirstVisitor(); + + //Act + var status = enumerable.Visit(ref visitor); + + //Assert + var expected = enumerable.ToEnumerable().ToArray().First(); + Assert.Equal(expected, visitor.First); + Assert.Equal(VisitStatus.VisitorFinished, status); + } + } + + internal struct ListVisitor : IVisitor + { + public List List { get; } + public ListVisitor(List list) + { + this.List = list; + } + + public bool Visit(T input) + { + List.Add(input); + return true; + } + } + + internal struct FirstVisitor : IVisitor + { + public T First; + public bool Visit(T input) + { + First = input; + return false; + } } } \ No newline at end of file diff --git a/src/StructLinq.Tests/ConcatTests.cs b/src/StructLinq.Tests/ConcatTests.cs index 49b6539c..4588292b 100644 --- a/src/StructLinq.Tests/ConcatTests.cs +++ b/src/StructLinq.Tests/ConcatTests.cs @@ -41,6 +41,5 @@ public void ShouldSameAsSystemWithInterface() var value = array1.ToStructEnumerable().Concat(array2.ToStructEnumerable()).ToArray(); Assert.Equal(expected, value); } - } } diff --git a/src/StructLinq.Tests/Utils/Collections/PooledListVisitorTests.cs b/src/StructLinq.Tests/Utils/Collections/PooledListVisitorTests.cs new file mode 100644 index 00000000..d872b727 --- /dev/null +++ b/src/StructLinq.Tests/Utils/Collections/PooledListVisitorTests.cs @@ -0,0 +1,22 @@ +using System.Buffers; +using System.Linq; +using StructLinq.Utils.Collections; +using Xunit; + +namespace StructLinq.Tests.Utils.Collections +{ + public class PooledListVisitorTests + { + [Fact] + public void ShouldCopyArray() + { + var visitor = new PooledListVisitor(0, ArrayPool.Shared); + var array = Enumerable.Range(-1, 50).ToArray(); + + array.ToStructEnumerable().Visit(ref visitor); + + var value = visitor.PooledList.ToArray(); + Assert.Equal(array, value); + } + } +} diff --git a/src/StructLinq/Array/ArrayEnumerable.cs b/src/StructLinq/Array/ArrayEnumerable.cs index f8a846bc..4ae54c89 100644 --- a/src/StructLinq/Array/ArrayEnumerable.cs +++ b/src/StructLinq/Array/ArrayEnumerable.cs @@ -52,5 +52,20 @@ public T Get(int i) return array[start + i]; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var count = Count; + var s = start; + for (int i = 0; i < count; i++) + { + if (!visitor.Visit(array[s+i])) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } \ No newline at end of file diff --git a/src/StructLinq/Concat/ConcatEnumerable.cs b/src/StructLinq/Concat/ConcatEnumerable.cs index a8c79430..cd2f3a95 100644 --- a/src/StructLinq/Concat/ConcatEnumerable.cs +++ b/src/StructLinq/Concat/ConcatEnumerable.cs @@ -24,5 +24,15 @@ public ConcatEnumerator GetEnumerator() var enum2 = enumerable2.GetEnumerator(); return new ConcatEnumerator(ref enum1, ref enum2); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var visitStatus = enumerable1.Visit(ref visitor); + if (visitStatus == VisitStatus.VisitorFinished) + return visitStatus; + return enumerable2.Visit(ref visitor); + } } } diff --git a/src/StructLinq/Distinct/DistinctEnumerable.cs b/src/StructLinq/Distinct/DistinctEnumerable.cs index 4ab41ea5..a1d88c33 100644 --- a/src/StructLinq/Distinct/DistinctEnumerable.cs +++ b/src/StructLinq/Distinct/DistinctEnumerable.cs @@ -31,8 +31,20 @@ public DistinctEnumerable(ref TEnumerable enumerable, TComparer comparer, int ca public DistinctEnumerator GetEnumerator() { var enumerator = enumerable.GetEnumerator(); - return new DistinctEnumerator(ref enumerator, capacity, bucketPool, slotPool, - comparer); + return new DistinctEnumerator(ref enumerator, capacity, bucketPool, slotPool, comparer); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; } } } \ No newline at end of file diff --git a/src/StructLinq/Empty/EmptyEnumerable.cs b/src/StructLinq/Empty/EmptyEnumerable.cs index a61aeb61..86674a0b 100644 --- a/src/StructLinq/Empty/EmptyEnumerable.cs +++ b/src/StructLinq/Empty/EmptyEnumerable.cs @@ -9,5 +9,11 @@ public readonly EmptyEnumerator GetEnumerator() { return new EmptyEnumerator(); } + + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Except/ExceptEnumerable.cs b/src/StructLinq/Except/ExceptEnumerable.cs index da0e65c4..3075e30a 100644 --- a/src/StructLinq/Except/ExceptEnumerable.cs +++ b/src/StructLinq/Except/ExceptEnumerable.cs @@ -39,5 +39,18 @@ public ExceptEnumerator GetEnumerator( var set = new PooledSet(capacity, bucketPool, slotPool, comparer); return new ExceptEnumerator(ref enum1, ref enum2, ref set); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/IEnumerable/StructEnumerableFromIEnumerable.cs b/src/StructLinq/IEnumerable/StructEnumerableFromIEnumerable.cs index 6e7b2ac2..9f80141e 100644 --- a/src/StructLinq/IEnumerable/StructEnumerableFromIEnumerable.cs +++ b/src/StructLinq/IEnumerable/StructEnumerableFromIEnumerable.cs @@ -18,5 +18,18 @@ public GenericEnumerator GetEnumerator() { return new GenericEnumerator(inner.GetEnumerator()); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/IList/IListEnumerable.cs b/src/StructLinq/IList/IListEnumerable.cs index 92d2134c..86bf8aa5 100644 --- a/src/StructLinq/IList/IListEnumerable.cs +++ b/src/StructLinq/IList/IListEnumerable.cs @@ -51,5 +51,20 @@ public T Get(int i) { return list[start + i]; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var count = Count; + var s = start; + for (int i = 0; i < count; i++) + { + if (!visitor.Visit(list[s+i])) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } \ No newline at end of file diff --git a/src/StructLinq/IStructEnumerable.cs b/src/StructLinq/IStructEnumerable.cs index b6ea5455..a89a0315 100644 --- a/src/StructLinq/IStructEnumerable.cs +++ b/src/StructLinq/IStructEnumerable.cs @@ -4,5 +4,8 @@ public interface IStructEnumerable where TEnumerator : struct, IStructEnumerator { TEnumerator GetEnumerator(); + + VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor; } } diff --git a/src/StructLinq/IVisitor.cs b/src/StructLinq/IVisitor.cs new file mode 100644 index 00000000..8ce29f1a --- /dev/null +++ b/src/StructLinq/IVisitor.cs @@ -0,0 +1,7 @@ +namespace StructLinq +{ + public interface IVisitor + { + bool Visit(T input); + } +} diff --git a/src/StructLinq/Intersect/IntersectEnumerable.cs b/src/StructLinq/Intersect/IntersectEnumerable.cs index be3f11b8..d9933499 100644 --- a/src/StructLinq/Intersect/IntersectEnumerable.cs +++ b/src/StructLinq/Intersect/IntersectEnumerable.cs @@ -39,5 +39,18 @@ public IntersectEnumerator GetEnumerat var set = new PooledSet(capacity, bucketPool, slotPool, comparer); return new IntersectEnumerator(ref enum1, ref enum2, ref set); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/OrderBy/OrderByKeyEnumerable.cs b/src/StructLinq/OrderBy/OrderByKeyEnumerable.cs index ef711d28..0dea6255 100644 --- a/src/StructLinq/OrderBy/OrderByKeyEnumerable.cs +++ b/src/StructLinq/OrderBy/OrderByKeyEnumerable.cs @@ -71,5 +71,18 @@ public OrderByEnumerator GetEnumerator() keys.Dispose(); return new OrderByEnumerator(indexes, datas, size, indexPool); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/OrderBy/OrderEnumerable.cs b/src/StructLinq/OrderBy/OrderEnumerable.cs index 5cacf60c..01034e70 100644 --- a/src/StructLinq/OrderBy/OrderEnumerable.cs +++ b/src/StructLinq/OrderBy/OrderEnumerable.cs @@ -50,5 +50,18 @@ public OrderByEnumerator GetEnumerator() QuickSort.Sort(indexes, 0, size -1, datas.Items, ref comp, ascending); return new OrderByEnumerator(indexes, datas, size, indexPool); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Range/RangeEnumerable.cs b/src/StructLinq/Range/RangeEnumerable.cs index 6060cbdc..d2abbe3f 100644 --- a/src/StructLinq/Range/RangeEnumerable.cs +++ b/src/StructLinq/Range/RangeEnumerable.cs @@ -51,5 +51,20 @@ public int Get(int i) { return start + i; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var n = Count; + var s = start; + for (int i = 0; i < n; i++) + { + if (!visitor.Visit(s+i)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Repeat/RepeatEnumerable.cs b/src/StructLinq/Repeat/RepeatEnumerable.cs index cac88dc6..34a454e3 100644 --- a/src/StructLinq/Repeat/RepeatEnumerable.cs +++ b/src/StructLinq/Repeat/RepeatEnumerable.cs @@ -47,5 +47,18 @@ public T Get(int i) { return element; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + for (int i = 0; i < count; i++) + { + if (!visitor.Visit(element)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Reverse/ReverseEnumerable.cs b/src/StructLinq/Reverse/ReverseEnumerable.cs index ce8f3603..5e7302cb 100644 --- a/src/StructLinq/Reverse/ReverseEnumerable.cs +++ b/src/StructLinq/Reverse/ReverseEnumerable.cs @@ -33,5 +33,18 @@ internal TEnumerable Enumerable [MethodImpl(MethodImplOptions.AggressiveInlining)] get => enumerable; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Reverse/ReverseStructCollection.cs b/src/StructLinq/Reverse/ReverseStructCollection.cs index 04451e94..a1635a74 100644 --- a/src/StructLinq/Reverse/ReverseStructCollection.cs +++ b/src/StructLinq/Reverse/ReverseStructCollection.cs @@ -44,5 +44,22 @@ public T Get(int i) { return structCollection.Get(structCollection.Count - 1 - start - i); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var c = structCollection.Count; + var s = start; + var count = Count; + for (int i = 0; i < count; i++) + { + var input = structCollection.Get(c - 1 - s - i); + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } \ No newline at end of file diff --git a/src/StructLinq/Select/RefSelectCollection.cs b/src/StructLinq/Select/RefSelectCollection.cs index cd5c79c9..ac52d41c 100644 --- a/src/StructLinq/Select/RefSelectCollection.cs +++ b/src/StructLinq/Select/RefSelectCollection.cs @@ -49,5 +49,17 @@ public TOut Get(int i) return function.Eval(inner.Get(i)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) where TVisitor : IVisitor + { + var count = Count; + for (int i = 0; i < count; i++) + { + var tout = Get(i); + if (!visitor.Visit(tout)) + return VisitStatus.VisitorFinished; + } + return VisitStatus.EnumeratorFinished; + } } } \ No newline at end of file diff --git a/src/StructLinq/Select/RefSelectEnumerable.cs b/src/StructLinq/Select/RefSelectEnumerable.cs index c4228d81..158d9d98 100644 --- a/src/StructLinq/Select/RefSelectEnumerable.cs +++ b/src/StructLinq/Select/RefSelectEnumerable.cs @@ -24,5 +24,18 @@ public RefSelectEnumerator GetEnumerator() var typedEnumerator = inner.GetEnumerator(); return new RefSelectEnumerator(ref function, ref typedEnumerator); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } \ No newline at end of file diff --git a/src/StructLinq/Select/SelectCollection.cs b/src/StructLinq/Select/SelectCollection.cs index 0fb774d5..bef4e689 100644 --- a/src/StructLinq/Select/SelectCollection.cs +++ b/src/StructLinq/Select/SelectCollection.cs @@ -48,6 +48,15 @@ public TOut Get(int i) { return function(inner.Get(i)); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) where TVisitor : IVisitor + { + var selectVisitor = new SelectVisitor(function, ref visitor); + var visitStatus = inner.Visit(ref selectVisitor); + visitor = selectVisitor.visitor; + return visitStatus; + } } public struct SelectCollection : IStructCollection> @@ -97,5 +106,13 @@ public TOut Get(int i) return function.Eval(inner.Get(i)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) where TVisitor : IVisitor + { + var selectVisitor = new SelectVisitor(ref function, ref visitor); + var visitStatus = inner.Visit(ref selectVisitor); + visitor = selectVisitor.visitor; + return visitStatus; + } } } \ No newline at end of file diff --git a/src/StructLinq/Select/SelectEnumerable.cs b/src/StructLinq/Select/SelectEnumerable.cs index e9cca92a..ad97b7a5 100644 --- a/src/StructLinq/Select/SelectEnumerable.cs +++ b/src/StructLinq/Select/SelectEnumerable.cs @@ -25,9 +25,40 @@ public SelectEnumerator GetEnumerator() var typedEnumerator = inner.GetEnumerator(); return new SelectEnumerator(ref function, ref typedEnumerator); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var selectVisitor = new SelectVisitor(ref function, ref visitor); + var visitStatus = inner.Visit(ref selectVisitor); + visitor = selectVisitor.visitor; + return visitStatus; + } } - - public struct SelectEnumerable : IStructEnumerable> + + internal struct SelectVisitor : IVisitor + where TFunction : struct, IFunction where TVisitor : IVisitor + { + public TFunction function; + public TVisitor visitor; + + public SelectVisitor(ref TFunction function, ref TVisitor visitor) + { + this.function = function; + this.visitor = visitor; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(TIn input) + { + var output = function.Eval(input); + return visitor.Visit(output); + } + } + + public struct + SelectEnumerable : IStructEnumerable> where TEnumerator : struct, IStructEnumerator where TEnumerable : IStructEnumerable { @@ -48,6 +79,35 @@ public SelectEnumerator GetEnumerator() var typedEnumerator = inner.GetEnumerator(); return new SelectEnumerator(function, ref typedEnumerator); } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var selectVisitor = new SelectVisitor(function, ref visitor); + var visitStatus = inner.Visit(ref selectVisitor); + visitor = selectVisitor.visitor; + return visitStatus; + } + } + + internal struct SelectVisitor : IVisitor where TVisitor : IVisitor + { + public Func function; + public TVisitor visitor; + + public SelectVisitor(Func function, ref TVisitor visitor) + { + this.function = function; + this.visitor = visitor; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(TIn input) + { + var output = function(input); + return visitor.Visit(output); + } } } diff --git a/src/StructLinq/Skip/SkipEnumerable.cs b/src/StructLinq/Skip/SkipEnumerable.cs index 9b928925..b8ae8d8b 100644 --- a/src/StructLinq/Skip/SkipEnumerable.cs +++ b/src/StructLinq/Skip/SkipEnumerable.cs @@ -21,5 +21,18 @@ public SkipEnumerator GetEnumerator() var enumerator = inner.GetEnumerator(); return new SkipEnumerator(ref enumerator, count); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Sum/SumStructEnumerable.cs b/src/StructLinq/Sum/SumStructEnumerable.cs index e191d3fd..7b8c647a 100644 --- a/src/StructLinq/Sum/SumStructEnumerable.cs +++ b/src/StructLinq/Sum/SumStructEnumerable.cs @@ -12,14 +12,129 @@ namespace StructLinq public static partial class StructEnumerable { + private struct SumInt16Visitor : IVisitor + { + public Int16 sum; + public SumInt16Visitor(Int16 sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(Int16 input) + { + sum += input; + return true; + } + } + + private struct SumFuncInt16Visitor : IVisitor + { + public Int16 sum; + private readonly Func func; + public SumFuncInt16Visitor(Int16 sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionInt16Visitor : IVisitor + where TFunc : IFunction + { + public Int16 sum; + private readonly TFunc func; + public SumIFunctionInt16Visitor(Int16 sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Int16 SumInt16(ref TEnumerator enumerator) + public static Int16 Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumInt16Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int16 Sum(this TEnumerable enumerable, Func> _) where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumInt16Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int16 Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncInt16Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int16 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncInt16Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int16 Sum(this IStructEnumerable enumerable, + IFunction func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumIFunctionInt16Visitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int16 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + where TFunc : IFunction + { + var sumVisitor = new SumIFunctionInt16Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Int16 SumInt16(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { Int16 result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; @@ -27,14 +142,14 @@ private static Int16 SumInt16(ref TEnumerator enumerator) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Int16 SumInt16(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { Int16 result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; @@ -42,38 +157,38 @@ private static Int16 SumInt16(ref TEnumerator enumerator, [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Int16 SumInt16(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { Int16 result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int16 Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static Int16 Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt16(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int16 Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static Int16 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); return SumInt16(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int16 Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static Int16 Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt16(ref enumerator, func); @@ -82,18 +197,18 @@ public static Int16 Sum(this IStructEnumerable en [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int16 Sum(this TEnumerable enumerable, Func func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt16(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int16 Sum(this IStructEnumerable enumerable, + public static Int16 Sum(this IStructCollection enumerable, IFunction func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt16>(ref enumerator, ref func); @@ -102,10 +217,10 @@ public static Int16 Sum(this IStructEnumerable en [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int16 Sum(this TEnumerable enumerable, ref TFunc func, - Func> _, + Func> _, Func> __) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { var enumerator = enumerable.GetEnumerator(); @@ -117,14 +232,129 @@ public static Int16 Sum(this TEnumerable enume public static partial class StructEnumerable { + private struct SumInt32Visitor : IVisitor + { + public Int32 sum; + public SumInt32Visitor(Int32 sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(Int32 input) + { + sum += input; + return true; + } + } + + private struct SumFuncInt32Visitor : IVisitor + { + public Int32 sum; + private readonly Func func; + public SumFuncInt32Visitor(Int32 sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionInt32Visitor : IVisitor + where TFunc : IFunction + { + public Int32 sum; + private readonly TFunc func; + public SumIFunctionInt32Visitor(Int32 sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Int32 SumInt32(ref TEnumerator enumerator) + public static Int32 Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumInt32Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int32 Sum(this TEnumerable enumerable, Func> _) where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumInt32Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int32 Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncInt32Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int32 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncInt32Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int32 Sum(this IStructEnumerable enumerable, + IFunction func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumIFunctionInt32Visitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int32 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + where TFunc : IFunction + { + var sumVisitor = new SumIFunctionInt32Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Int32 SumInt32(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { Int32 result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; @@ -132,14 +362,14 @@ private static Int32 SumInt32(ref TEnumerator enumerator) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Int32 SumInt32(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { Int32 result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; @@ -147,38 +377,38 @@ private static Int32 SumInt32(ref TEnumerator enumerator, [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Int32 SumInt32(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { Int32 result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int32 Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static Int32 Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt32(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int32 Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static Int32 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); return SumInt32(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int32 Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static Int32 Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt32(ref enumerator, func); @@ -187,18 +417,18 @@ public static Int32 Sum(this IStructEnumerable en [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int32 Sum(this TEnumerable enumerable, Func func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt32(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Int32 Sum(this IStructEnumerable enumerable, + public static Int32 Sum(this IStructCollection enumerable, IFunction func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumInt32>(ref enumerator, ref func); @@ -207,10 +437,10 @@ public static Int32 Sum(this IStructEnumerable en [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int32 Sum(this TEnumerable enumerable, ref TFunc func, - Func> _, + Func> _, Func> __) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { var enumerator = enumerable.GetEnumerator(); @@ -222,54 +452,63 @@ public static Int32 Sum(this TEnumerable enume public static partial class StructEnumerable { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Int64 SumInt64(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + private struct SumInt64Visitor : IVisitor { - Int64 result = 0; - while (enumerator.MoveNext()) + public Int64 sum; + public SumInt64Visitor(Int64 sum) { - result += enumerator.Current; + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(Int64 input) + { + sum += input; + return true; } - enumerator.Dispose(); - return result; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Int64 SumInt64(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + + private struct SumFuncInt64Visitor : IVisitor { - Int64 result = 0; - while (enumerator.MoveNext()) + public Int64 sum; + private readonly Func func; + public SumFuncInt64Visitor(Int64 sum, Func func) { - var current = enumerator.Current; - result += func.Eval(current); + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; } - enumerator.Dispose(); - return result; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Int64 SumInt64(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + private struct SumIFunctionInt64Visitor : IVisitor + where TFunc : IFunction { - Int64 result = 0; - while (enumerator.MoveNext()) + public Int64 sum; + private readonly TFunc func; + public SumIFunctionInt64Visitor(Int64 sum, TFunc func) { - var current = enumerator.Current; - result += func(current); + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; } - enumerator.Dispose(); - return result; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int64 Sum(this IStructEnumerable enumerable) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumInt64(ref enumerator); + var sumVisitor = new SumInt64Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -277,16 +516,18 @@ public static Int64 Sum(this TEnumerable enumerable, F where TEnumerator : struct, IStructEnumerator where TEnumerable : struct, IStructEnumerable { - var enumerator = enumerable.GetEnumerator(); - return SumInt64(ref enumerator); + var sumVisitor = new SumInt64Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Int64 Sum(this IStructEnumerable enumerable, Func func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumInt64(ref enumerator, func); + var sumVisitor = new SumFuncInt64Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -296,8 +537,9 @@ public static Int64 Sum(this TEnumerable enumerable, where TEnumerable : struct, IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumInt64(ref enumerator, func); + var sumVisitor = new SumFuncInt64Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -305,8 +547,9 @@ public static Int64 Sum(this IStructEnumerable en IFunction func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumInt64>(ref enumerator, ref func); + var sumVisitor = new SumIFunctionInt64Visitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -318,100 +561,215 @@ public static Int64 Sum(this TEnumerable enume where TEnumerator : struct, IStructEnumerator where TFunc : IFunction { - var enumerator = enumerable.GetEnumerator(); - return SumInt64(ref enumerator,ref func); - } - - } + var sumVisitor = new SumIFunctionInt64Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } - public static partial class StructEnumerable - { [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt16 SumUInt16(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + private static Int64 SumInt64(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { - UInt16 result = 0; - while (enumerator.MoveNext()) + Int64 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt16 SumUInt16(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + private static Int64 SumInt64(ref TEnumerator enumerator, ref TFunc func) + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction { - UInt16 result = 0; - while (enumerator.MoveNext()) + Int64 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt16 SumUInt16(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + private static Int64 SumInt64(ref TEnumerator enumerator, Func func) + where TEnumerator : struct, ICollectionEnumerator { - UInt16 result = 0; - while (enumerator.MoveNext()) + Int64 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt16 Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static Int64 Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumUInt16(ref enumerator); + return SumInt64(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt16 Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static Int64 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); - return SumUInt16(ref enumerator); + return SumInt64(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt16 Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static Int64 Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumUInt16(ref enumerator, func); + return SumInt64(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt16 Sum(this TEnumerable enumerable, - Func func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + public static Int64 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumUInt16(ref enumerator, func); + return SumInt64(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt16 Sum(this IStructEnumerable enumerable, + public static Int64 Sum(this IStructCollection enumerable, + IFunction func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumInt64>(ref enumerator, ref func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Int64 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + var enumerator = enumerable.GetEnumerator(); + return SumInt64(ref enumerator,ref func); + } + + } + + + public static partial class StructEnumerable + { + private struct SumUInt16Visitor : IVisitor + { + public UInt16 sum; + public SumUInt16Visitor(UInt16 sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(UInt16 input) + { + sum += input; + return true; + } + } + + private struct SumFuncUInt16Visitor : IVisitor + { + public UInt16 sum; + private readonly Func func; + public SumFuncUInt16Visitor(UInt16 sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionUInt16Visitor : IVisitor + where TFunc : IFunction + { + public UInt16 sum; + private readonly TFunc func; + public SumIFunctionUInt16Visitor(UInt16 sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumUInt16Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumUInt16Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncUInt16Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncUInt16Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this IStructEnumerable enumerable, IFunction func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt16>(ref enumerator, ref func); + var sumVisitor = new SumIFunctionUInt16Visitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -423,63 +781,174 @@ public static UInt16 Sum(this TEnumerable enum where TEnumerator : struct, IStructEnumerator where TFunc : IFunction { - var enumerator = enumerable.GetEnumerator(); - return SumUInt16(ref enumerator,ref func); - } - - } + var sumVisitor = new SumIFunctionUInt16Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } - public static partial class StructEnumerable - { [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt32 SumUInt32(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + private static UInt16 SumUInt16(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { - UInt32 result = 0; - while (enumerator.MoveNext()) + UInt16 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt32 SumUInt32(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + private static UInt16 SumUInt16(ref TEnumerator enumerator, ref TFunc func) + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction { - UInt32 result = 0; - while (enumerator.MoveNext()) + UInt16 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt32 SumUInt32(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + private static UInt16 SumUInt16(ref TEnumerator enumerator, Func func) + where TEnumerator : struct, ICollectionEnumerator { - UInt32 result = 0; - while (enumerator.MoveNext()) + UInt16 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt16(ref enumerator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt16(ref enumerator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt16(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt16(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this IStructCollection enumerable, + IFunction func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt16>(ref enumerator, ref func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt16 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt16(ref enumerator,ref func); + } + + } + + + public static partial class StructEnumerable + { + private struct SumUInt32Visitor : IVisitor + { + public UInt32 sum; + public SumUInt32Visitor(UInt32 sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(UInt32 input) + { + sum += input; + return true; + } + } + + private struct SumFuncUInt32Visitor : IVisitor + { + public UInt32 sum; + private readonly Func func; + public SumFuncUInt32Visitor(UInt32 sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionUInt32Visitor : IVisitor + where TFunc : IFunction + { + public UInt32 sum; + private readonly TFunc func; + public SumIFunctionUInt32Visitor(UInt32 sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UInt32 Sum(this IStructEnumerable enumerable) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt32(ref enumerator); + var sumVisitor = new SumUInt32Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -487,16 +956,18 @@ public static UInt32 Sum(this TEnumerable enumerable, where TEnumerator : struct, IStructEnumerator where TEnumerable : struct, IStructEnumerable { - var enumerator = enumerable.GetEnumerator(); - return SumUInt32(ref enumerator); + var sumVisitor = new SumUInt32Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UInt32 Sum(this IStructEnumerable enumerable, Func func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt32(ref enumerator, func); + var sumVisitor = new SumFuncUInt32Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -506,8 +977,9 @@ public static UInt32 Sum(this TEnumerable enumerable, where TEnumerable : struct, IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt32(ref enumerator, func); + var sumVisitor = new SumFuncUInt32Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -515,8 +987,9 @@ public static UInt32 Sum(this IStructEnumerable e IFunction func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt32>(ref enumerator, ref func); + var sumVisitor = new SumIFunctionUInt32Visitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -528,218 +1001,770 @@ public static UInt32 Sum(this TEnumerable enum where TEnumerator : struct, IStructEnumerator where TFunc : IFunction { - var enumerator = enumerable.GetEnumerator(); - return SumUInt32(ref enumerator,ref func); - } - - } + var sumVisitor = new SumIFunctionUInt32Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } - public static partial class StructEnumerable - { [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt64 SumUInt64(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + private static UInt32 SumUInt32(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { - UInt64 result = 0; - while (enumerator.MoveNext()) + UInt32 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt64 SumUInt64(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + private static UInt32 SumUInt32(ref TEnumerator enumerator, ref TFunc func) + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction { - UInt64 result = 0; - while (enumerator.MoveNext()) + UInt32 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static UInt64 SumUInt64(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + private static UInt32 SumUInt32(ref TEnumerator enumerator, Func func) + where TEnumerator : struct, ICollectionEnumerator { - UInt64 result = 0; - while (enumerator.MoveNext()) + UInt32 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt64 Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static UInt32 Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumUInt64(ref enumerator); + return SumUInt32(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt64 Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static UInt32 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); - return SumUInt64(ref enumerator); + return SumUInt32(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt64 Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static UInt32 Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumUInt64(ref enumerator, func); + return SumUInt32(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt32 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt32(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt32 Sum(this IStructCollection enumerable, + IFunction func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt32>(ref enumerator, ref func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt32 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt32(ref enumerator,ref func); + } + + } + + + public static partial class StructEnumerable + { + private struct SumUInt64Visitor : IVisitor + { + public UInt64 sum; + public SumUInt64Visitor(UInt64 sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(UInt64 input) + { + sum += input; + return true; + } + } + + private struct SumFuncUInt64Visitor : IVisitor + { + public UInt64 sum; + private readonly Func func; + public SumFuncUInt64Visitor(UInt64 sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionUInt64Visitor : IVisitor + where TFunc : IFunction + { + public UInt64 sum; + private readonly TFunc func; + public SumIFunctionUInt64Visitor(UInt64 sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumUInt64Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumUInt64Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncUInt64Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncUInt64Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this IStructEnumerable enumerable, + IFunction func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumIFunctionUInt64Visitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + where TFunc : IFunction + { + var sumVisitor = new SumIFunctionUInt64Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static UInt64 SumUInt64(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator + { + UInt64 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) + { + result += enumerator.Get(i); + } + enumerator.Dispose(); + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static UInt64 SumUInt64(ref TEnumerator enumerator, ref TFunc func) + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + UInt64 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) + { + result += func.Eval(enumerator.Get(i)); + } + enumerator.Dispose(); + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static UInt64 SumUInt64(ref TEnumerator enumerator, Func func) + where TEnumerator : struct, ICollectionEnumerator + { + UInt64 result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) + { + result += func(enumerator.Get(i)); + } + enumerator.Dispose(); + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt64(ref enumerator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt64(ref enumerator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt64(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt64(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this IStructCollection enumerable, + IFunction func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt64>(ref enumerator, ref func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static UInt64 Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + var enumerator = enumerable.GetEnumerator(); + return SumUInt64(ref enumerator,ref func); + } + + } + + + public static partial class StructEnumerable + { + private struct SumSingleVisitor : IVisitor + { + public Single sum; + public SumSingleVisitor(Single sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(Single input) + { + sum += input; + return true; + } + } + + private struct SumFuncSingleVisitor : IVisitor + { + public Single sum; + private readonly Func func; + public SumFuncSingleVisitor(Single sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionSingleVisitor : IVisitor + where TFunc : IFunction + { + public Single sum; + private readonly TFunc func; + public SumIFunctionSingleVisitor(Single sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumSingleVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumSingleVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncSingleVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncSingleVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this IStructEnumerable enumerable, + IFunction func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumIFunctionSingleVisitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + where TFunc : IFunction + { + var sumVisitor = new SumIFunctionSingleVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Single SumSingle(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator + { + Single result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) + { + result += enumerator.Get(i); + } + enumerator.Dispose(); + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Single SumSingle(ref TEnumerator enumerator, ref TFunc func) + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + Single result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) + { + result += func.Eval(enumerator.Get(i)); + } + enumerator.Dispose(); + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static Single SumSingle(ref TEnumerator enumerator, Func func) + where TEnumerator : struct, ICollectionEnumerator + { + Single result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) + { + result += func(enumerator.Get(i)); + } + enumerator.Dispose(); + return result; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumSingle(ref enumerator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection + { + var enumerator = enumerable.GetEnumerator(); + return SumSingle(ref enumerator); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumSingle(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumSingle(ref enumerator, func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this IStructCollection enumerable, + IFunction func) + where TEnumerator : struct, ICollectionEnumerator + { + var enumerator = enumerable.GetEnumerator(); + return SumSingle>(ref enumerator, ref func); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Single Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction + { + var enumerator = enumerable.GetEnumerator(); + return SumSingle(ref enumerator,ref func); + } + + } + + + public static partial class StructEnumerable + { + private struct SumDoubleVisitor : IVisitor + { + public Double sum; + public SumDoubleVisitor(Double sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(Double input) + { + sum += input; + return true; + } + } + + private struct SumFuncDoubleVisitor : IVisitor + { + public Double sum; + private readonly Func func; + public SumFuncDoubleVisitor(Double sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionDoubleVisitor : IVisitor + where TFunc : IFunction + { + public Double sum; + private readonly TFunc func; + public SumIFunctionDoubleVisitor(Double sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Double Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumDoubleVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Double Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumDoubleVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Double Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncDoubleVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt64 Sum(this TEnumerable enumerable, - Func func, + public static Double Sum(this TEnumerable enumerable, + Func func, Func> _) where TEnumerable : struct, IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt64(ref enumerator, func); + var sumVisitor = new SumFuncDoubleVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt64 Sum(this IStructEnumerable enumerable, - IFunction func) + public static Double Sum(this IStructEnumerable enumerable, + IFunction func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumUInt64>(ref enumerator, ref func); + var sumVisitor = new SumIFunctionDoubleVisitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static UInt64 Sum(this TEnumerable enumerable, + public static Double Sum(this TEnumerable enumerable, ref TFunc func, Func> _, - Func> __) + Func> __) where TEnumerable : struct, IStructEnumerable where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + where TFunc : IFunction { - var enumerator = enumerable.GetEnumerator(); - return SumUInt64(ref enumerator,ref func); - } - - } + var sumVisitor = new SumIFunctionDoubleVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } - public static partial class StructEnumerable - { [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Single SumSingle(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + private static Double SumDouble(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { - Single result = 0; - while (enumerator.MoveNext()) + Double result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Single SumSingle(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + private static Double SumDouble(ref TEnumerator enumerator, ref TFunc func) + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction { - Single result = 0; - while (enumerator.MoveNext()) + Double result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Single SumSingle(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + private static Double SumDouble(ref TEnumerator enumerator, Func func) + where TEnumerator : struct, ICollectionEnumerator { - Single result = 0; - while (enumerator.MoveNext()) + Double result = 0; + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Single Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static Double Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumSingle(ref enumerator); + return SumDouble(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Single Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static Double Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); - return SumSingle(ref enumerator); + return SumDouble(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Single Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static Double Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumSingle(ref enumerator, func); + return SumDouble(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Single Sum(this TEnumerable enumerable, - Func func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + public static Double Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumSingle(ref enumerator, func); + return SumDouble(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Single Sum(this IStructEnumerable enumerable, - IFunction func) - where TEnumerator : struct, IStructEnumerator + public static Double Sum(this IStructCollection enumerable, + IFunction func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); - return SumSingle>(ref enumerator, ref func); + return SumDouble>(ref enumerator, ref func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Single Sum(this TEnumerable enumerable, + public static Double Sum(this TEnumerable enumerable, ref TFunc func, - Func> _, - Func> __) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + Func> _, + Func> __) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator + where TFunc : IFunction { var enumerator = enumerable.GetEnumerator(); - return SumSingle(ref enumerator,ref func); + return SumDouble(ref enumerator,ref func); } } @@ -747,119 +1772,129 @@ public static Single Sum(this TEnumerable enum public static partial class StructEnumerable { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Double SumDouble(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + private struct SumByteVisitor : IVisitor { - Double result = 0; - while (enumerator.MoveNext()) + public Byte sum; + public SumByteVisitor(Byte sum) { - result += enumerator.Current; + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(Byte input) + { + sum += input; + return true; } - enumerator.Dispose(); - return result; } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Double SumDouble(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + + private struct SumFuncByteVisitor : IVisitor { - Double result = 0; - while (enumerator.MoveNext()) + public Byte sum; + private readonly Func func; + public SumFuncByteVisitor(Byte sum, Func func) { - var current = enumerator.Current; - result += func.Eval(current); + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; } - enumerator.Dispose(); - return result; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static Double SumDouble(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + private struct SumIFunctionByteVisitor : IVisitor + where TFunc : IFunction { - Double result = 0; - while (enumerator.MoveNext()) + public Byte sum; + private readonly TFunc func; + public SumIFunctionByteVisitor(Byte sum, TFunc func) { - var current = enumerator.Current; - result += func(current); + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; } - enumerator.Dispose(); - return result; } - + [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Double Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static Byte Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumDouble(ref enumerator); + var sumVisitor = new SumByteVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Double Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static Byte Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable { - var enumerator = enumerable.GetEnumerator(); - return SumDouble(ref enumerator); + var sumVisitor = new SumByteVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Double Sum(this IStructEnumerable enumerable, Func func) + public static Byte Sum(this IStructEnumerable enumerable, Func func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumDouble(ref enumerator, func); + var sumVisitor = new SumFuncByteVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Double Sum(this TEnumerable enumerable, - Func func, + public static Byte Sum(this TEnumerable enumerable, + Func func, Func> _) where TEnumerable : struct, IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumDouble(ref enumerator, func); + var sumVisitor = new SumFuncByteVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Double Sum(this IStructEnumerable enumerable, - IFunction func) + public static Byte Sum(this IStructEnumerable enumerable, + IFunction func) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return SumDouble>(ref enumerator, ref func); + var sumVisitor = new SumIFunctionByteVisitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Double Sum(this TEnumerable enumerable, + public static Byte Sum(this TEnumerable enumerable, ref TFunc func, Func> _, - Func> __) + Func> __) where TEnumerable : struct, IStructEnumerable where TEnumerator : struct, IStructEnumerator - where TFunc : IFunction + where TFunc : IFunction { - var enumerator = enumerable.GetEnumerator(); - return SumDouble(ref enumerator,ref func); - } - - } + var sumVisitor = new SumIFunctionByteVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } - public static partial class StructEnumerable - { [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Byte SumByte(ref TEnumerator enumerator) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { Byte result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; @@ -867,14 +1902,14 @@ private static Byte SumByte(ref TEnumerator enumerator) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Byte SumByte(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { Byte result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; @@ -882,38 +1917,38 @@ private static Byte SumByte(ref TEnumerator enumerator, re [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Byte SumByte(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { Byte result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Byte Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static Byte Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumByte(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Byte Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static Byte Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); return SumByte(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Byte Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static Byte Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumByte(ref enumerator, func); @@ -922,18 +1957,18 @@ public static Byte Sum(this IStructEnumerable enu [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Byte Sum(this TEnumerable enumerable, Func func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumByte(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Byte Sum(this IStructEnumerable enumerable, + public static Byte Sum(this IStructCollection enumerable, IFunction func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumByte>(ref enumerator, ref func); @@ -942,10 +1977,10 @@ public static Byte Sum(this IStructEnumerable enu [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Byte Sum(this TEnumerable enumerable, ref TFunc func, - Func> _, + Func> _, Func> __) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { var enumerator = enumerable.GetEnumerator(); @@ -957,14 +1992,129 @@ public static Byte Sum(this TEnumerable enumer public static partial class StructEnumerable { + private struct SumSByteVisitor : IVisitor + { + public SByte sum; + public SumSByteVisitor(SByte sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(SByte input) + { + sum += input; + return true; + } + } + + private struct SumFuncSByteVisitor : IVisitor + { + public SByte sum; + private readonly Func func; + public SumFuncSByteVisitor(SByte sum, Func func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunctionSByteVisitor : IVisitor + where TFunc : IFunction + { + public SByte sum; + private readonly TFunc func; + public SumIFunctionSByteVisitor(SByte sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static SByte SumSByte(ref TEnumerator enumerator) + public static SByte Sum(this IStructEnumerable enumerable) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumSByteVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SByte Sum(this TEnumerable enumerable, Func> _) where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructEnumerable + { + var sumVisitor = new SumSByteVisitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SByte Sum(this IStructEnumerable enumerable, Func func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncSByteVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SByte Sum(this TEnumerable enumerable, + Func func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFuncSByteVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SByte Sum(this IStructEnumerable enumerable, + IFunction func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumIFunctionSByteVisitor>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static SByte Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func> __) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + where TFunc : IFunction + { + var sumVisitor = new SumIFunctionSByteVisitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static SByte SumSByte(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator { SByte result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; @@ -972,14 +2122,14 @@ private static SByte SumSByte(ref TEnumerator enumerator) [MethodImpl(MethodImplOptions.AggressiveInlining)] private static SByte SumSByte(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { SByte result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; @@ -987,38 +2137,38 @@ private static SByte SumSByte(ref TEnumerator enumerator, [MethodImpl(MethodImplOptions.AggressiveInlining)] private static SByte SumSByte(ref TEnumerator enumerator, Func func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { SByte result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SByte Sum(this IStructEnumerable enumerable) - where TEnumerator : struct, IStructEnumerator + public static SByte Sum(this IStructCollection enumerable) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumSByte(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SByte Sum(this TEnumerable enumerable, Func> _) - where TEnumerator : struct, IStructEnumerator - where TEnumerable : struct, IStructEnumerable + public static SByte Sum(this TEnumerable enumerable, Func> _) + where TEnumerator : struct, ICollectionEnumerator + where TEnumerable : struct, IStructCollection { var enumerator = enumerable.GetEnumerator(); return SumSByte(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SByte Sum(this IStructEnumerable enumerable, Func func) - where TEnumerator : struct, IStructEnumerator + public static SByte Sum(this IStructCollection enumerable, Func func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumSByte(ref enumerator, func); @@ -1027,18 +2177,18 @@ public static SByte Sum(this IStructEnumerable en [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SByte Sum(this TEnumerable enumerable, Func func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumSByte(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SByte Sum(this IStructEnumerable enumerable, + public static SByte Sum(this IStructCollection enumerable, IFunction func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return SumSByte>(ref enumerator, ref func); @@ -1047,10 +2197,10 @@ public static SByte Sum(this IStructEnumerable en [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SByte Sum(this TEnumerable enumerable, ref TFunc func, - Func> _, + Func> _, Func> __) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction { var enumerator = enumerable.GetEnumerator(); diff --git a/src/StructLinq/Sum/SumStructEnumerable.tt b/src/StructLinq/Sum/SumStructEnumerable.tt index 13e63d3c..b4e03d02 100644 --- a/src/StructLinq/Sum/SumStructEnumerable.tt +++ b/src/StructLinq/Sum/SumStructEnumerable.tt @@ -34,14 +34,129 @@ namespace StructLinq public static partial class StructEnumerable { + private struct Sum<#= t.Name #>Visitor : IVisitor<<#= t.Name #>> + { + public <#= t.Name #> sum; + public Sum<#= t.Name #>Visitor(<#= t.Name #> sum) + { + this.sum = sum; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(<#= t.Name #> input) + { + sum += input; + return true; + } + } + + private struct SumFunc<#= t.Name #>Visitor : IVisitor + { + public <#= t.Name #> sum; + private readonly Func> func; + public SumFunc<#= t.Name #>Visitor(<#= t.Name #> sum, Func> func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func(input); + return true; + } + } + + private struct SumIFunction<#= t.Name #>Visitor : IVisitor + where TFunc : IFunction> + { + public <#= t.Name #> sum; + private readonly TFunc func; + public SumIFunction<#= t.Name #>Visitor(<#= t.Name #> sum, TFunc func) + { + this.sum = sum; + this.func = func; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + sum += func.Eval(input); + return true; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static <#= t.Name #> Sum<#= t.Name #>(ref TEnumerator enumerator) + public static <#= t.Name #> Sum(this IStructEnumerable<<#= t.Name #>, TEnumerator> enumerable) where TEnumerator : struct, IStructEnumerator<<#= t.Name #>> + { + var sumVisitor = new Sum<#= t.Name #>Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static <#= t.Name #> Sum(this TEnumerable enumerable, Func, TEnumerator>> _) + where TEnumerator : struct, IStructEnumerator<<#= t.Name #>> + where TEnumerable : struct, IStructEnumerable<<#= t.Name #>, TEnumerator> + { + var sumVisitor = new Sum<#= t.Name #>Visitor(0); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static <#= t.Name #> Sum(this IStructEnumerable enumerable, Func> func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFunc<#= t.Name #>Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static <#= t.Name #> Sum(this TEnumerable enumerable, + Func> func, + Func> _) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumFunc<#= t.Name #>Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static <#= t.Name #> Sum(this IStructEnumerable enumerable, + IFunction> func) + where TEnumerator : struct, IStructEnumerator + { + var sumVisitor = new SumIFunction<#= t.Name #>Visitor>>(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static <#= t.Name #> Sum(this TEnumerable enumerable, + ref TFunc func, + Func> _, + Func>> __) + where TEnumerable : struct, IStructEnumerable + where TEnumerator : struct, IStructEnumerator + where TFunc : IFunction> + { + var sumVisitor = new SumIFunction<#= t.Name #>Visitor(0, func); + enumerable.Visit(ref sumVisitor); + return sumVisitor.sum; } + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static <#= t.Name #> Sum<#= t.Name #>(ref TEnumerator enumerator) + where TEnumerator : struct, ICollectionEnumerator<<#= t.Name #>> { <#= t.Name #> result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - result += enumerator.Current; + result += enumerator.Get(i); } enumerator.Dispose(); return result; @@ -49,14 +164,14 @@ namespace StructLinq [MethodImpl(MethodImplOptions.AggressiveInlining)] private static <#= t.Name #> Sum<#= t.Name #>(ref TEnumerator enumerator, ref TFunc func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction> { <#= t.Name #> result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func.Eval(current); + result += func.Eval(enumerator.Get(i)); } enumerator.Dispose(); return result; @@ -64,38 +179,38 @@ namespace StructLinq [MethodImpl(MethodImplOptions.AggressiveInlining)] private static <#= t.Name #> Sum<#= t.Name #>(ref TEnumerator enumerator, Func> func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { <#= t.Name #> result = 0; - while (enumerator.MoveNext()) + var count = enumerator.Count; + for (int i = 0; i < count; i++) { - var current = enumerator.Current; - result += func(current); + result += func(enumerator.Get(i)); } enumerator.Dispose(); return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static <#= t.Name #> Sum(this IStructEnumerable<<#= t.Name #>, TEnumerator> enumerable) - where TEnumerator : struct, IStructEnumerator<<#= t.Name #>> + public static <#= t.Name #> Sum(this IStructCollection<<#= t.Name #>, TEnumerator> enumerable) + where TEnumerator : struct, ICollectionEnumerator<<#= t.Name #>> { var enumerator = enumerable.GetEnumerator(); return Sum<#= t.Name #>(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static <#= t.Name #> Sum(this TEnumerable enumerable, Func, TEnumerator>> _) - where TEnumerator : struct, IStructEnumerator<<#= t.Name #>> - where TEnumerable : struct, IStructEnumerable<<#= t.Name #>, TEnumerator> + public static <#= t.Name #> Sum(this TEnumerable enumerable, Func, TEnumerator>> _) + where TEnumerator : struct, ICollectionEnumerator<<#= t.Name #>> + where TEnumerable : struct, IStructCollection<<#= t.Name #>, TEnumerator> { var enumerator = enumerable.GetEnumerator(); return Sum<#= t.Name #>(ref enumerator); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static <#= t.Name #> Sum(this IStructEnumerable enumerable, Func> func) - where TEnumerator : struct, IStructEnumerator + public static <#= t.Name #> Sum(this IStructCollection enumerable, Func> func) + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return Sum<#= t.Name #>(ref enumerator, func); @@ -104,18 +219,18 @@ namespace StructLinq [MethodImpl(MethodImplOptions.AggressiveInlining)] public static <#= t.Name #> Sum(this TEnumerable enumerable, Func> func, - Func> _) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + Func> _) + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return Sum<#= t.Name #>(ref enumerator, func); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static <#= t.Name #> Sum(this IStructEnumerable enumerable, + public static <#= t.Name #> Sum(this IStructCollection enumerable, IFunction> func) - where TEnumerator : struct, IStructEnumerator + where TEnumerator : struct, ICollectionEnumerator { var enumerator = enumerable.GetEnumerator(); return Sum<#= t.Name #>>>(ref enumerator, ref func); @@ -124,10 +239,10 @@ namespace StructLinq [MethodImpl(MethodImplOptions.AggressiveInlining)] public static <#= t.Name #> Sum(this TEnumerable enumerable, ref TFunc func, - Func> _, + Func> _, Func>> __) - where TEnumerable : struct, IStructEnumerable - where TEnumerator : struct, IStructEnumerator + where TEnumerable : struct, IStructCollection + where TEnumerator : struct, ICollectionEnumerator where TFunc : IFunction> { var enumerator = enumerable.GetEnumerator(); diff --git a/src/StructLinq/Take/TakeEnumerable.cs b/src/StructLinq/Take/TakeEnumerable.cs index 8ae66913..912b86f4 100644 --- a/src/StructLinq/Take/TakeEnumerable.cs +++ b/src/StructLinq/Take/TakeEnumerable.cs @@ -21,5 +21,18 @@ public TakeEnumerator GetEnumerator() var enumerator = inner.GetEnumerator(); return new TakeEnumerator(ref enumerator, count); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/ToArray/StructEnumerable.ToArray.cs b/src/StructLinq/ToArray/StructEnumerable.ToArray.cs index 259ffde4..6f7649a2 100644 --- a/src/StructLinq/ToArray/StructEnumerable.ToArray.cs +++ b/src/StructLinq/ToArray/StructEnumerable.ToArray.cs @@ -5,23 +5,11 @@ using System.Runtime.CompilerServices; using StructLinq.Utils.Collections; +// ReSharper disable once CheckNamespace namespace StructLinq { public static partial class StructEnumerable { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static T[] ToArray(ref TEnumerator enumerator, - int capacity, - ArrayPool pool) - where TEnumerator : struct, IStructEnumerator - { - var list = new PooledList(capacity, pool); - PoolLists.Fill(ref list, ref enumerator); - var array = list.ToArray(); - list.Dispose(); - return array; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private static T[] ToRefArray(ref TEnumerator enumerator, int capacity, @@ -44,8 +32,11 @@ public static T[] ToArray( where TEnumerable : IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return ToArray(ref enumerator, capacity, pool); + var visitor = new PooledListVisitor(capacity, pool); + enumerable.Visit(ref visitor); + var array = visitor.PooledList.ToArray(); + visitor.Dispose(); + return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -57,16 +48,22 @@ public static T[] ToArray( where TEnumerable : IStructEnumerable where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return ToArray(ref enumerator, capacity, ArrayPool.Shared); + var visitor = new PooledListVisitor(capacity, ArrayPool.Shared); + enumerable.Visit(ref visitor); + var array = visitor.PooledList.ToArray(); + visitor.Dispose(); + return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T[] ToArray(this IStructEnumerable enumerable, int capacity, ArrayPool pool) where TEnumerator : struct, IStructEnumerator { - var enumerator = enumerable.GetEnumerator(); - return ToArray(ref enumerator, capacity, pool); + var visitor = new PooledListVisitor(capacity, pool); + enumerable.Visit(ref visitor); + var array = visitor.PooledList.ToArray(); + visitor.Dispose(); + return array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/StructLinq/Union/UnionEnumerable.cs b/src/StructLinq/Union/UnionEnumerable.cs index e30b0128..3b1ccf1c 100644 --- a/src/StructLinq/Union/UnionEnumerable.cs +++ b/src/StructLinq/Union/UnionEnumerable.cs @@ -39,5 +39,18 @@ public UnionEnumerator GetEnumerator() var set = new PooledSet(capacity, bucketPool, slotPool, comparer); return new UnionEnumerator(ref enum1, ref enum2, ref set); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + foreach (var input in this) + { + if (!visitor.Visit(input)) + return VisitStatus.VisitorFinished; + } + + return VisitStatus.EnumeratorFinished; + } } } diff --git a/src/StructLinq/Utils/Collections/PooledListVisitor.cs b/src/StructLinq/Utils/Collections/PooledListVisitor.cs new file mode 100644 index 00000000..8a68c8b4 --- /dev/null +++ b/src/StructLinq/Utils/Collections/PooledListVisitor.cs @@ -0,0 +1,29 @@ +using System; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace StructLinq.Utils.Collections +{ + internal struct PooledListVisitor : IVisitor, IDisposable + { + public PooledList PooledList; + + public PooledListVisitor(int capacity, ArrayPool pool) + { + PooledList = new PooledList(capacity, pool); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(T input) + { + PooledList.Add(input); + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Dispose() + { + PooledList.Dispose(); + } + } +} diff --git a/src/StructLinq/VisitStatus.cs b/src/StructLinq/VisitStatus.cs new file mode 100644 index 00000000..347f017a --- /dev/null +++ b/src/StructLinq/VisitStatus.cs @@ -0,0 +1,8 @@ +namespace StructLinq +{ + public enum VisitStatus + { + VisitorFinished, + EnumeratorFinished + } +} \ No newline at end of file diff --git a/src/StructLinq/Where/WhereEnumerable.cs b/src/StructLinq/Where/WhereEnumerable.cs index b8497462..0ff93182 100644 --- a/src/StructLinq/Where/WhereEnumerable.cs +++ b/src/StructLinq/Where/WhereEnumerable.cs @@ -22,6 +22,34 @@ public WhereEnumerator GetEnumerator() var enumerator = inner.GetEnumerator(); return new WhereEnumerator(ref function, ref enumerator); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var selector = new WhereVisitor(ref function, ref visitor); + var visitStatus = inner.Visit(ref selector); + visitor = selector.visitor; + return visitStatus; + } + + private struct WhereVisitor : IVisitor + where TVisitor : IVisitor + { + public TFunction function; + public TVisitor visitor; + public WhereVisitor(ref TFunction function, ref TVisitor visitor) + { + this.function = function; + this.visitor = visitor; + } + public bool Visit(TIn input) + { + if (function.Eval(input)) + return visitor.Visit(input); + return true; + } + } } public struct WhereEnumerable : IStructEnumerable> @@ -42,5 +70,36 @@ public WhereEnumerator GetEnumerator() var enumerator = inner.GetEnumerator(); return new WhereEnumerator(function, ref enumerator); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public VisitStatus Visit(ref TVisitor visitor) + where TVisitor : IVisitor + { + var whereVisitor = new WhereVisitor(function, ref visitor); + var visitStatus = inner.Visit(ref whereVisitor); + visitor = whereVisitor.visitor; + return visitStatus; + } + } + + internal struct WhereVisitor : IVisitor + where TVisitor : IVisitor + { + public Func function; + public TVisitor visitor; + + public WhereVisitor(Func function, ref TVisitor visitor) + { + this.function = function; + this.visitor = visitor; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Visit(TIn input) + { + if (function(input)) + return visitor.Visit(input); + return true; + } } }