Skip to content

Commit 76ffb84

Browse files
Copilotdadhi
andauthored
Replace Dictionary with SmallMap16; inline sibling iteration in hot paths
Agent-Logs-Url: https://github.com/dadhi/FastExpressionCompiler/sessions/869f4a36-48ea-4e91-b89b-1079e333c0d4 Co-authored-by: dadhi <39516+dadhi@users.noreply.github.com>
1 parent d565578 commit 76ffb84

1 file changed

Lines changed: 34 additions & 23 deletions

File tree

src/FastExpressionCompiler/FlatExpression.cs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ public Idx LinkList(Idx[] indices)
242242
return indices[0];
243243
}
244244

245+
// Allocates an enumerator — suitable for tests and diagnostics; avoid in hot paths.
245246
public IEnumerable<Idx> Siblings(Idx head)
246247
{
247248
var cur = head;
@@ -253,9 +254,13 @@ public IEnumerable<Idx> Siblings(Idx head)
253254
}
254255

255256
// Builds body after registering params so they are found in paramMap when encountered in the body.
256-
public SysExpr ToSystemExpression() => ToSystemExpression(RootIdx, new Dictionary<int, SysParam>());
257+
public SysExpr ToSystemExpression()
258+
{
259+
var paramMap = default(SmallMap16<int, SysParam, IntEq>);
260+
return ToSystemExpression(RootIdx, ref paramMap);
261+
}
257262

258-
private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramMap)
263+
private SysExpr ToSystemExpression(Idx nodeIdx, ref SmallMap16<int, SysParam, IntEq> paramMap)
259264
{
260265
if (nodeIdx.IsNil)
261266
throw new InvalidOperationException("Cannot convert nil Idx to System.Linq.Expressions");
@@ -274,11 +279,9 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
274279

275280
case ExpressionType.Parameter:
276281
{
277-
if (!paramMap.TryGetValue(nodeIdx.It, out var p))
278-
{
282+
ref var p = ref paramMap.Map.AddOrGetValueRef(nodeIdx.It, out var found);
283+
if (!found)
279284
p = SysExpr.Parameter(node.Type, node.Info as string);
280-
paramMap[nodeIdx.It] = p;
281-
}
282285
return p;
283286
}
284287

@@ -291,20 +294,20 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
291294
var paramExprs = new List<SysParam>();
292295
if (paramIdxs != null)
293296
foreach (var pIdx in paramIdxs)
294-
paramExprs.Add((SysParam)ToSystemExpression(pIdx, paramMap));
295-
var body = ToSystemExpression(node.ChildIdx, paramMap);
297+
paramExprs.Add((SysParam)ToSystemExpression(pIdx, ref paramMap));
298+
var body = ToSystemExpression(node.ChildIdx, ref paramMap);
296299
return SysExpr.Lambda(node.Type, body, paramExprs);
297300
}
298301

299302
case ExpressionType.New:
300-
return SysExpr.New((ConstructorInfo)node.Info, SiblingList(node.ChildIdx, paramMap));
303+
return SysExpr.New((ConstructorInfo)node.Info, SiblingList(node.ChildIdx, ref paramMap));
301304

302305
case ExpressionType.Call:
303306
{
304307
var method = (MethodInfo)node.Info;
305308
return method.IsStatic
306-
? SysExpr.Call(method, SiblingList(node.ChildIdx, paramMap))
307-
: SysExpr.Call(ToSystemExpression(node.ChildIdx, paramMap), method, SiblingList(node.ExtraIdx, paramMap));
309+
? SysExpr.Call(method, SiblingList(node.ChildIdx, ref paramMap))
310+
: SysExpr.Call(ToSystemExpression(node.ChildIdx, ref paramMap), method, SiblingList(node.ExtraIdx, ref paramMap));
308311
}
309312

310313
case ExpressionType.Add:
@@ -332,8 +335,8 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
332335
case ExpressionType.Power:
333336
case ExpressionType.Coalesce:
334337
return SysExpr.MakeBinary(node.NodeType,
335-
ToSystemExpression(node.ChildIdx, paramMap),
336-
ToSystemExpression(node.ExtraIdx, paramMap),
338+
ToSystemExpression(node.ChildIdx, ref paramMap),
339+
ToSystemExpression(node.ExtraIdx, ref paramMap),
337340
false, node.Info as MethodInfo);
338341

339342
case ExpressionType.Negate:
@@ -353,24 +356,28 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
353356
case ExpressionType.PreDecrementAssign:
354357
case ExpressionType.PostDecrementAssign:
355358
return SysExpr.MakeUnary(node.NodeType,
356-
ToSystemExpression(node.ChildIdx, paramMap),
359+
ToSystemExpression(node.ChildIdx, ref paramMap),
357360
node.Type, node.Info as MethodInfo);
358361

359362
case ExpressionType.Conditional:
360363
return SysExpr.Condition(
361-
ToSystemExpression(node.ChildIdx, paramMap),
362-
ToSystemExpression(node.ExtraIdx, paramMap),
363-
ToSystemExpression(NodeAt(node.ExtraIdx).NextIdx, paramMap),
364+
ToSystemExpression(node.ChildIdx, ref paramMap),
365+
ToSystemExpression(node.ExtraIdx, ref paramMap),
366+
ToSystemExpression(NodeAt(node.ExtraIdx).NextIdx, ref paramMap),
364367
node.Type);
365368

366369
case ExpressionType.Block:
367370
{
368-
var exprs = SiblingList(node.ChildIdx, paramMap);
371+
var exprs = SiblingList(node.ChildIdx, ref paramMap);
369372
if (node.ExtraIdx.IsNil)
370373
return SysExpr.Block(node.Type, exprs);
371374
var vars = new List<SysParam>();
372-
foreach (var vIdx in Siblings(node.ExtraIdx))
373-
vars.Add((SysParam)ToSystemExpression(vIdx, paramMap));
375+
var vCur = node.ExtraIdx;
376+
while (!vCur.IsNil)
377+
{
378+
vars.Add((SysParam)ToSystemExpression(vCur, ref paramMap));
379+
vCur = NodeAt(vCur).NextIdx;
380+
}
374381
return SysExpr.Block(node.Type, vars, exprs);
375382
}
376383

@@ -380,11 +387,15 @@ private SysExpr ToSystemExpression(Idx nodeIdx, Dictionary<int, SysParam> paramM
380387
}
381388
}
382389

383-
private List<SysExpr> SiblingList(Idx head, Dictionary<int, SysParam> paramMap)
390+
private List<SysExpr> SiblingList(Idx head, ref SmallMap16<int, SysParam, IntEq> paramMap)
384391
{
385392
var list = new List<SysExpr>();
386-
foreach (var idx in Siblings(head))
387-
list.Add(ToSystemExpression(idx, paramMap));
393+
var cur = head;
394+
while (!cur.IsNil)
395+
{
396+
list.Add(ToSystemExpression(cur, ref paramMap));
397+
cur = NodeAt(cur).NextIdx;
398+
}
388399
return list;
389400
}
390401

0 commit comments

Comments
 (0)