Skip to content

Commit d35c348

Browse files
committed
update ToArray and ToList specialization
1 parent 8cf25a0 commit d35c348

4 files changed

Lines changed: 101 additions & 38 deletions

File tree

LinqGen.Generator/Instructions/Evaluations/Local/ToArrayEvaluation.cs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,47 @@ public ToArrayEvaluation(in LinqGenExpression expression, int id) : base(express
2525

2626
protected override IEnumerable<StatementSyntax> RenderInitialization()
2727
{
28-
ExpressionSyntax countExpression = Upstream.SupportCount
29-
? CountProperty
30-
: LiteralExpression(0);
28+
if (Upstream.SupportCount)
29+
{
30+
yield return LocalDeclarationStatement(VarName("array").Identifier,
31+
ObjectCreationExpression(ArrayType(Upstream.OutputElementType,
32+
SingletonList(ArrayRankSpecifier(SingletonSeparatedList((ExpressionSyntax)CountProperty))))));
3133

32-
yield return UsingLocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
33-
PooledListType(Upstream.OutputElementType, Upstream.OutputElementSymbol.IsUnmanagedType),
34-
ArgumentList(countExpression), null));
34+
yield return LocalDeclarationStatement(VarName("index").Identifier, LiteralExpression(-1));
35+
}
36+
else
37+
{
38+
yield return UsingLocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
39+
PooledListType(Upstream.OutputElementType, Upstream.OutputElementSymbol.IsUnmanagedType),
40+
ArgumentList(LiteralExpression(0)), null));
41+
}
3542
}
3643

3744
protected override IEnumerable<StatementSyntax> RenderAccumulation()
3845
{
39-
yield return ExpressionStatement(InvocationExpression(
40-
MemberAccessExpression(VarName("list"), AddMethod), ArgumentList(CurrentPlaceholder)));
46+
if (Upstream.SupportCount)
47+
{
48+
yield return ExpressionStatement(SimpleAssignmentExpression(
49+
ElementAccessExpression(VarName("array"), PreIncrementExpression(VarName("index"))),
50+
CurrentPlaceholder));
51+
}
52+
else
53+
{
54+
yield return ExpressionStatement(InvocationExpression(
55+
MemberAccessExpression(VarName("list"), AddMethod), ArgumentList(CurrentPlaceholder)));
56+
}
4157
}
4258

4359
protected override IEnumerable<StatementSyntax> RenderReturn()
4460
{
45-
yield return ReturnStatement(InvocationExpression(VarName("list"), IdentifierName("ToArray")));
61+
if (Upstream.SupportCount)
62+
{
63+
yield return ReturnStatement(VarName("array"));
64+
}
65+
else
66+
{
67+
yield return ReturnStatement(InvocationExpression(VarName("list"), IdentifierName("ToArray")));
68+
}
4669
}
4770
}
4871
}

LinqGen.Generator/Instructions/Evaluations/Local/ToListEvaluation.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,17 @@ public ToListEvaluation(in LinqGenExpression expression, int id) : base(expressi
2525

2626
protected override IEnumerable<StatementSyntax> RenderInitialization()
2727
{
28-
ExpressionSyntax countExpression = Upstream.SupportCount
29-
? CountProperty
30-
: LiteralExpression(0);
31-
32-
yield return UsingLocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
33-
PooledListType(Upstream.OutputElementType, Upstream.OutputElementSymbol.IsUnmanagedType),
34-
ArgumentList(countExpression), null));
28+
if (Upstream.SupportCount)
29+
{
30+
yield return LocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
31+
ReturnType, ArgumentList(CountProperty), null));
32+
}
33+
else
34+
{
35+
yield return UsingLocalDeclarationStatement(VarName("list").Identifier, ObjectCreationExpression(
36+
PooledListType(Upstream.OutputElementType, Upstream.OutputElementSymbol.IsUnmanagedType),
37+
ArgumentList(LiteralExpression(0)), null));
38+
}
3539
}
3640

3741
protected override IEnumerable<StatementSyntax> RenderAccumulation()
@@ -42,7 +46,14 @@ protected override IEnumerable<StatementSyntax> RenderAccumulation()
4246

4347
protected override IEnumerable<StatementSyntax> RenderReturn()
4448
{
45-
yield return ReturnStatement(InvocationExpression(VarName("list"), IdentifierName("ToList")));
49+
if (Upstream.SupportCount)
50+
{
51+
yield return ReturnStatement(VarName("list"));
52+
}
53+
else
54+
{
55+
yield return ReturnStatement(InvocationExpression(VarName("list"), IdentifierName("ToList")));
56+
}
4657
}
4758
}
4859
}

docs/BenchmarksResults/ArraySelectToArray.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,26 @@ Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
1616
```
1717
| Method | Count | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
1818
|------------------- |-------- |----------------:|--------------:|--------------:|----------------:|------:|--------:|---------:|---------:|---------:|----------:|------------:|
19-
| **Linq** | **100** | **209.08 ns** | **0.849 ns** | **0.753 ns** | **209.08 ns** | **1.00** | **0.00** | **0.2255** | **-** | **-** | **472 B** | **1.00** |
20-
| LinqGenDelegate | 100 | 346.70 ns | 2.979 ns | 2.326 ns | 347.02 ns | 1.66 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
21-
| LinqGenStruct | 100 | 242.80 ns | 1.499 ns | 1.403 ns | 242.84 ns | 1.16 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
22-
| StructLinqDelegate | 100 | 188.95 ns | 1.086 ns | 0.907 ns | 189.19 ns | 0.90 | 0.01 | 0.2332 | - | - | 488 B | 1.03 |
23-
| StructLinqStruct | 100 | 133.64 ns | 0.668 ns | 0.625 ns | 133.69 ns | 0.64 | 0.00 | 0.2027 | - | - | 424 B | 0.90 |
24-
| HyperLinqDelegate | 100 | 165.05 ns | 1.186 ns | 1.109 ns | 165.06 ns | 0.79 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
25-
| HyperLinqStruct | 100 | 90.29 ns | 1.789 ns | 2.197 ns | 89.50 ns | 0.44 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
19+
| **Linq** | **100** | **209.88 ns** | **4.209 ns** | **4.133 ns** | **209.68 ns** | **1.00** | **0.00** | **0.2255** | **-** | **-** | **472 B** | **1.00** |
20+
| LinqGenDelegate | 100 | 176.34 ns | 3.497 ns | 2.730 ns | 175.88 ns | 0.85 | 0.02 | 0.2027 | - | - | 424 B | 0.90 |
21+
| LinqGenStruct | 100 | 123.28 ns | 0.911 ns | 0.852 ns | 123.16 ns | 0.59 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
22+
| StructLinqDelegate | 100 | 189.28 ns | 0.970 ns | 0.907 ns | 189.08 ns | 0.90 | 0.02 | 0.2332 | - | - | 488 B | 1.03 |
23+
| StructLinqStruct | 100 | 131.79 ns | 0.626 ns | 0.586 ns | 131.81 ns | 0.63 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
24+
| HyperLinqDelegate | 100 | 162.57 ns | 1.204 ns | 1.126 ns | 162.54 ns | 0.78 | 0.02 | 0.2027 | - | - | 424 B | 0.90 |
25+
| HyperLinqStruct | 100 | 88.85 ns | 0.603 ns | 0.564 ns | 88.71 ns | 0.42 | 0.01 | 0.2027 | - | - | 424 B | 0.90 |
2626
| | | | | | | | | | | | | |
27-
| **Linq** | **10000** | **14,875.08 ns** | **112.167 ns** | **104.921 ns** | **14,879.36 ns** | **1.00** | **0.00** | **18.8599** | **-** | **-** | **40072 B** | **1.00** |
28-
| LinqGenDelegate | 10000 | 25,392.28 ns | 181.279 ns | 151.376 ns | 25,387.92 ns | 1.70 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
29-
| LinqGenStruct | 10000 | 13,012.96 ns | 114.216 ns | 101.249 ns | 12,986.16 ns | 0.87 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
30-
| StructLinqDelegate | 10000 | 15,217.20 ns | 120.857 ns | 107.137 ns | 15,198.11 ns | 1.02 | 0.01 | 18.8599 | - | - | 40088 B | 1.00 |
31-
| StructLinqStruct | 10000 | 8,898.67 ns | 98.978 ns | 92.584 ns | 8,895.96 ns | 0.60 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
32-
| HyperLinqDelegate | 10000 | 14,820.10 ns | 57.128 ns | 50.642 ns | 14,829.18 ns | 1.00 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
33-
| HyperLinqStruct | 10000 | 7,869.10 ns | 43.230 ns | 40.438 ns | 7,868.94 ns | 0.53 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
27+
| **Linq** | **10000** | **14,752.00 ns** | **108.763 ns** | **101.737 ns** | **14,762.95 ns** | **1.00** | **0.00** | **18.8599** | **-** | **-** | **40072 B** | **1.00** |
28+
| LinqGenDelegate | 10000 | 16,038.42 ns | 97.299 ns | 86.253 ns | 16,059.89 ns | 1.09 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
29+
| LinqGenStruct | 10000 | 10,386.22 ns | 55.209 ns | 51.642 ns | 10,361.48 ns | 0.70 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
30+
| StructLinqDelegate | 10000 | 15,325.30 ns | 143.429 ns | 111.980 ns | 15,281.17 ns | 1.04 | 0.01 | 18.8599 | - | - | 40088 B | 1.00 |
31+
| StructLinqStruct | 10000 | 8,842.63 ns | 97.082 ns | 90.810 ns | 8,834.91 ns | 0.60 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
32+
| HyperLinqDelegate | 10000 | 14,852.29 ns | 189.805 ns | 177.544 ns | 14,882.14 ns | 1.01 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
33+
| HyperLinqStruct | 10000 | 7,857.39 ns | 82.847 ns | 73.442 ns | 7,847.71 ns | 0.53 | 0.01 | 18.8599 | - | - | 40024 B | 1.00 |
3434
| | | | | | | | | | | | | |
35-
| **Linq** | **1000000** | **1,679,397.30 ns** | **32,799.598 ns** | **39,045.588 ns** | **1,676,840.62 ns** | **1.00** | **0.00** | **117.1875** | **117.1875** | **117.1875** | **4000198 B** | **1.00** |
36-
| LinqGenDelegate | 1000000 | 3,006,251.81 ns | 44,880.723 ns | 41,981.456 ns | 2,998,421.06 ns | 1.80 | 0.06 | 179.6875 | 179.6875 | 179.6875 | 4000144 B | 1.00 |
37-
| LinqGenStruct | 1000000 | 1,748,168.46 ns | 34,776.098 ns | 37,210.035 ns | 1,746,142.25 ns | 1.05 | 0.04 | 179.6875 | 179.6875 | 179.6875 | 4000143 B | 1.00 |
38-
| StructLinqDelegate | 1000000 | 1,720,865.56 ns | 34,255.933 ns | 35,178.322 ns | 1,717,945.80 ns | 1.03 | 0.03 | 113.2813 | 113.2813 | 113.2813 | 4000226 B | 1.00 |
39-
| StructLinqStruct | 1000000 | 1,031,713.25 ns | 19,782.910 ns | 19,429.463 ns | 1,030,354.90 ns | 0.62 | 0.02 | 267.5781 | 267.5781 | 267.5781 | 4000197 B | 1.00 |
40-
| HyperLinqDelegate | 1000000 | 1,691,122.16 ns | 32,665.605 ns | 44,713.049 ns | 1,695,468.55 ns | 1.00 | 0.02 | 121.0938 | 121.0938 | 121.0938 | 4000105 B | 1.00 |
41-
| HyperLinqStruct | 1000000 | 972,956.75 ns | 27,555.295 ns | 80,380.088 ns | 949,792.54 ns | 0.54 | 0.02 | 176.7578 | 176.7578 | 176.7578 | 4000140 B | 1.00 |
35+
| **Linq** | **1000000** | **1,669,594.72 ns** | **30,436.249 ns** | **29,892.467 ns** | **1,663,139.04 ns** | **1.00** | **0.00** | **121.0938** | **121.0938** | **121.0938** | **4000248 B** | **1.00** |
36+
| LinqGenDelegate | 1000000 | 1,875,272.06 ns | 36,618.289 ns | 61,180.935 ns | 1,868,626.30 ns | 1.12 | 0.04 | 132.8125 | 132.8125 | 132.8125 | 4000111 B | 1.00 |
37+
| LinqGenStruct | 1000000 | 1,181,860.89 ns | 23,497.564 ns | 61,901.982 ns | 1,166,957.36 ns | 0.69 | 0.02 | 210.9375 | 210.9375 | 210.9375 | 4000160 B | 1.00 |
38+
| StructLinqDelegate | 1000000 | 1,698,988.68 ns | 25,871.989 ns | 22,934.844 ns | 1,691,950.48 ns | 1.02 | 0.01 | 109.3750 | 109.3750 | 109.3750 | 4000240 B | 1.00 |
39+
| StructLinqStruct | 1000000 | 1,081,186.28 ns | 22,422.494 ns | 63,608.884 ns | 1,062,034.91 ns | 0.64 | 0.03 | 279.2969 | 279.2969 | 279.2969 | 4000206 B | 1.00 |
40+
| HyperLinqDelegate | 1000000 | 1,675,176.31 ns | 31,800.523 ns | 31,232.366 ns | 1,670,419.27 ns | 1.00 | 0.02 | 109.3750 | 109.3750 | 109.3750 | 4000098 B | 1.00 |
41+
| HyperLinqStruct | 1000000 | 948,162.67 ns | 20,164.780 ns | 58,180.000 ns | 933,584.96 ns | 0.55 | 0.02 | 261.7188 | 260.7422 | 260.7422 | 4000192 B | 1.00 |
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## ListVsPooledList
2+
3+
### Source
4+
[ListVsPooledList.cs](../../LinqGen.Benchmarks/Cases/ListVsPooledList.cs)
5+
6+
### Results:
7+
``` ini
8+
9+
BenchmarkDotNet=v0.13.2, OS=macOS Monterey 12.3 (21E230) [Darwin 21.4.0]
10+
Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
11+
.NET SDK=7.0.100
12+
[Host] : .NET 6.0.2 (6.0.222.6406), Arm64 RyuJIT AdvSIMD
13+
DefaultJob : .NET 6.0.2 (6.0.222.6406), Arm64 RyuJIT AdvSIMD
14+
15+
16+
```
17+
| Method | Count | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Gen2 | Allocated | Alloc Ratio |
18+
|-------- |-------- |---------------:|-------------:|-------------:|------:|--------:|---------:|---------:|---------:|----------:|------------:|
19+
| **List** | **100** | **172.4 ns** | **0.81 ns** | **0.76 ns** | **1.00** | **0.00** | **0.2179** | **-** | **-** | **456 B** | **1.00** |
20+
| Native | 100 | 225.7 ns | 0.98 ns | 0.87 ns | 1.31 | 0.01 | - | - | - | - | 0.00 |
21+
| Managed | 100 | 216.5 ns | 1.12 ns | 0.99 ns | 1.26 | 0.01 | - | - | - | - | 0.00 |
22+
| | | | | | | | | | | | |
23+
| **List** | **10000** | **15,135.5 ns** | **107.64 ns** | **100.69 ns** | **1.00** | **0.00** | **18.8599** | **-** | **-** | **40056 B** | **1.00** |
24+
| Native | 10000 | 12,144.0 ns | 31.57 ns | 29.53 ns | 0.80 | 0.01 | - | - | - | - | 0.00 |
25+
| Managed | 10000 | 13,637.7 ns | 42.70 ns | 39.94 ns | 0.90 | 0.00 | - | - | - | - | 0.00 |
26+
| | | | | | | | | | | | |
27+
| **List** | **1000000** | **1,644,273.4 ns** | **32,770.02 ns** | **43,747.03 ns** | **1.00** | **0.00** | **123.0469** | **123.0469** | **123.0469** | **4000139 B** | **1.000** |
28+
| Native | 1000000 | 1,385,214.8 ns | 19,697.01 ns | 18,424.60 ns | 0.85 | 0.03 | - | - | - | 1 B | 0.000 |
29+
| Managed | 1000000 | 1,272,566.7 ns | 6,890.51 ns | 6,445.39 ns | 0.78 | 0.02 | - | - | - | 1 B | 0.000 |

0 commit comments

Comments
 (0)