Skip to content

Commit 46e0377

Browse files
author
MesTTo
committed
perf(core): applySubst skips empty subst and shares unchanged subtrees (fib 250->187ms, 270/270)
1 parent a75e672 commit 46e0377

1 file changed

Lines changed: 11 additions & 2 deletions

File tree

packages/core/src/substitution.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,20 @@ export function extendSubst(s: Subst, x: string, a: Atom): Subst {
2525
/** Apply `s` to an atom: replace each variable by its assigned value (one pass; the substituted
2626
* value is not itself re-substituted). */
2727
export function applySubst(s: Subst, a: Atom): Atom {
28+
if (s.length === 0) return a; // empty substitution is identity (no clone)
2829
switch (a.kind) {
2930
case "var":
3031
return lookupSubst(s, a.name) ?? a;
31-
case "expr":
32-
return { ...a, items: a.items.map((it) => applySubst(s, it)) };
32+
case "expr": {
33+
// Clone only if a child actually changed; otherwise share the reference (no allocation).
34+
let changed = false;
35+
const items = a.items.map((it) => {
36+
const r = applySubst(s, it);
37+
if (r !== it) changed = true;
38+
return r;
39+
});
40+
return changed ? { ...a, items } : a;
41+
}
3342
default:
3443
return a;
3544
}

0 commit comments

Comments
 (0)