Skip to content

Commit 68cc1ab

Browse files
authored
reduce allocations (#186) +semver:skip
* reduce allocations * fix tests * compute children list once on object construction * nrt refac iaddress
1 parent 751de7f commit 68cc1ab

File tree

55 files changed

+138
-158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+138
-158
lines changed

benchmarks/Readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ Apple M1 Pro, 1 CPU, 10 logical and 10 physical cores
1111
```
1212
| Method | Job | Runtime | Mean | Error | StdDev | Gen0 | Gen1 | Allocated |
1313
|--------|---------------|---------------|---------:|----------:|----------:|----------:|---------:|----------:|
14-
| Invoke | .NET 9.0 | .NET 9.0 | 9.496 ms | 0.1434 ms | 0.1341 ms | 1625.0000 | 546.8750 | 9.79 MB |
15-
| Invoke | NativeAOT 9.0 | NativeAOT 9.0 | 7.418 ms | 0.0217 ms | 0.0203 ms | 1632.8125 | 453.1250 | 9.78 MB |
14+
| Invoke | .NET 9.0 | .NET 9.0 | 9.525 ms | 0.1615 ms | 0.1658 ms | 1562.5000 | 500.0000 | 9.37 MB |
15+
| Invoke | NativeAOT 9.0 | NativeAOT 9.0 | 7.321 ms | 0.0544 ms | 0.0509 ms | 1562.5000 | 468.7500 | 9.36 MB |

src/Application/HydraScript.Application.CodeGeneration/Visitors/InstructionProvider.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Expressions.PrimaryExpressions;
1212
using HydraScript.Domain.FrontEnd.Parser.Impl.Ast.Nodes.Statements;
1313
using Microsoft.Extensions.DependencyInjection;
14-
using ZLinq;
1514

1615
namespace HydraScript.Application.CodeGeneration.Visitors;
1716

@@ -169,9 +168,9 @@ public AddressedInstructions Visit(WhileStatement visitable)
169168
}
170169

171170
result.AddRange(visitable.Statement.Accept(This));
172-
result.AsValueEnumerable()
173-
.OfType<Goto>().Where(g => g.JumpType is not null)
174-
.ToList().ForEach(g =>
171+
for (var address = result.Start; address != null; address = address.Next)
172+
{
173+
if (result[address] is Goto { JumpType: not null } g)
175174
{
176175
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
177176
switch (g.JumpType)
@@ -183,7 +182,8 @@ public AddressedInstructions Visit(WhileStatement visitable)
183182
g.SetJump(startBlockLabel);
184183
break;
185184
}
186-
});
185+
}
186+
}
187187
result.Add(new Goto(startBlockLabel));
188188

189189
result.Add(new EndBlock(BlockType.Loop, blockId), endBlockLabel.Name);
@@ -222,9 +222,11 @@ public AddressedInstructions Visit(IfStatement visitable)
222222
if (visitable.HasElseBlock())
223223
result.AddRange(visitable.Else?.Accept(This) ?? []);
224224

225-
result.AsValueEnumerable()
226-
.OfType<Goto>().Where(g => g.JumpType is InsideStatementJumpType.Break)
227-
.ToList().ForEach(g => g.SetJump(endBlockLabel));
225+
for (var address = result.Start; address != null; address = address.Next)
226+
{
227+
if (result[address] is Goto { JumpType: InsideStatementJumpType.Break } g)
228+
g.SetJump(endBlockLabel);
229+
}
228230

229231
result.Add(new EndBlock(BlockType.Condition, blockId), endBlockLabel.Name);
230232

src/Application/HydraScript.Application.StaticAnalysis/Impl/FunctionWithUndefinedReturnStorage.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ public FunctionDeclaration Get(FunctionSymbol symbol)
2121

2222
public void RemoveIfPresent(FunctionSymbol symbol) => _declarations.Remove(symbol.Id);
2323

24-
public IEnumerable<FunctionDeclaration> Flush() => _declarations.Keys.ToList()
25-
.Select(x =>
24+
public IEnumerable<FunctionDeclaration> Flush()
25+
{
26+
IReadOnlyList<FunctionSymbolId> keys = _declarations.Keys;
27+
while (keys.Count > 0)
2628
{
27-
var decl = _declarations[x];
28-
_declarations.Remove(x);
29-
return decl;
30-
});
29+
yield return _declarations[keys[0]];
30+
_declarations.Remove(keys[0]);
31+
}
32+
}
3133
}

src/Application/HydraScript.Application.StaticAnalysis/Visitors/SemanticChecker.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ public Type Visit(BinaryExpression visitable)
256256
"++" when lType is ArrayType { Type: Any } && rType is ArrayType { Type: Any } =>
257257
throw new CannotDefineType(visitable.Segment),
258258
"++" => lType is ArrayType lArrType && rType is ArrayType rArrType
259-
? new List<ArrayType> { lArrType, rArrType }.First(x => x.Type is not Any)
259+
? lArrType.Type is not Any ? lArrType : rArrType.Type is not Any ? rArrType : throw new CannotDefineType(visitable.Segment)
260260
: throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
261261
"::" when lType is not ArrayType =>
262262
throw new UnsupportedOperation(visitable.Segment, lType, visitable.Operator),
@@ -464,7 +464,7 @@ public Type Visit(CallExpression visitable)
464464

465465
public Type Visit(FunctionDeclaration visitable)
466466
{
467-
var parameters = visitable.Arguments.Select(x => x.TypeValue.Accept(_typeBuilder)).ToList();
467+
var parameters = visitable.Arguments.Select(x => x.TypeValue.Accept(_typeBuilder));
468468
var symbol = _symbolTables[visitable.Scope].FindSymbol(new FunctionSymbolId(visitable.Name, parameters))!;
469469
_functionStorage.RemoveIfPresent(symbol);
470470
visitable.Statements.Accept(This);

src/Domain/HydraScript.Domain.BackEnd/AddressedInstructions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ private void AddWithAddress(IExecutableInstruction instruction, IAddress newAddr
5454

5555
public void AddRange(AddressedInstructions instructions)
5656
{
57-
// ReSharper disable once ConstantConditionalAccessQualifier
58-
for (var address = instructions.Start; address != null; address = address?.Next)
57+
for (var address = instructions.Start; address != null; address = address.Next)
5958
{
6059
AddWithAddress(instructions[address], address);
6160
}

src/Domain/HydraScript.Domain.BackEnd/IAddress.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ namespace HydraScript.Domain.BackEnd;
22

33
public interface IAddress : IEquatable<IAddress>
44
{
5-
public IAddress Next { get; set; }
5+
public IAddress? Next { get; set; }
66

77
public string Name { get; }
88
}

src/Domain/HydraScript.Domain.BackEnd/IExecutableInstruction.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,5 @@ namespace HydraScript.Domain.BackEnd;
33
public interface IExecutableInstruction
44
{
55
public IAddress Address { get; set; }
6-
public IAddress Execute(IExecuteParams executeParams);
7-
public bool End { get; }
6+
public IAddress? Execute(IExecuteParams executeParams);
87
}

src/Domain/HydraScript.Domain.BackEnd/Impl/Addresses/HashAddress.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public class HashAddress(int seed) : IAddress
99

1010
private readonly Guid _id = Guid.NewGuid();
1111

12-
public IAddress Next { get; set; } = default!;
12+
public IAddress? Next { get; set; }
1313

1414
public string Name
1515
{

src/Domain/HydraScript.Domain.BackEnd/Impl/Addresses/Label.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public class Label(string name) : IAddress
44
{
55
public string Name { get; } = name;
66

7-
public IAddress Next { get; set; } = default!;
7+
public IAddress? Next { get; set; }
88

99
public bool Equals(IAddress? other) =>
1010
other is Label label &&
Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
namespace HydraScript.Domain.BackEnd.Impl.Instructions;
22

3-
public abstract class BlockLabel : Instruction
3+
public abstract class BlockLabel(
4+
BlockLabel.BlockPosition blockPosition,
5+
BlockType blockType,
6+
string blockId) : Instruction
47
{
5-
private readonly BlockPosition _blockPosition;
6-
private readonly BlockType _blockType;
7-
private readonly string _blockId;
8-
9-
protected BlockLabel(BlockPosition blockPosition, BlockType blockType, string blockId)
10-
{
11-
_blockPosition = blockPosition;
12-
_blockType = blockType;
13-
_blockId = blockId;
14-
}
15-
16-
public override IAddress Execute(IExecuteParams executeParams) =>
17-
Address.Next;
8+
public override IAddress? Execute(IExecuteParams executeParams) => Address.Next;
189

1910
protected override string ToStringInternal() =>
20-
$"{_blockPosition}{_blockType} {_blockId}";
11+
$"{blockPosition}{blockType} {blockId}";
2112

2213
protected enum BlockPosition
2314
{
@@ -33,14 +24,8 @@ public enum BlockType
3324
Condition
3425
}
3526

36-
public class BeginBlock : BlockLabel
37-
{
38-
public BeginBlock(BlockType blockType, string blockId) :
39-
base(BlockPosition.Begin, blockType, blockId) { }
40-
}
27+
public class BeginBlock(BlockType blockType, string blockId) :
28+
BlockLabel(BlockPosition.Begin, blockType, blockId);
4129

42-
public class EndBlock : BlockLabel
43-
{
44-
public EndBlock(BlockType blockType, string blockId) :
45-
base(BlockPosition.End, blockType, blockId) { }
46-
}
30+
public class EndBlock(BlockType blockType, string blockId) :
31+
BlockLabel(BlockPosition.End, blockType, blockId);

0 commit comments

Comments
 (0)