Skip to content

Commit 4da9c3e

Browse files
committed
perf(normalize): eliminate double normalization of params in callParts
callParts() was normalizing all parameters twice — once to calculate paramLoc via SpanList.range(), then again to build the positional args. The paramList computed on the first pass is already ASTv2.ExpressionNode[] and can be passed directly to builder.positional(). Safe because: - Symbol allocations (allocateFree/allocateNamed) are idempotent — they check indexOf/cache before allocating, so the second pass was pure waste. - PositionalArguments stores exprs as readonly — no mutation concern. - SpanList.range() only reads .loc from the nodes — no stored references. The duplication dates back to the original 2020 commit (8e11b91) where paramList was computed for SpanList.range() but then not reused for the builder, with an identical .map(normalize) call created instead. Impact (pnpm bench:precompile, prod dist, Apple M1 Max): - normalize large (33374c): 18.92ms → 17.72ms (6%) - precompile large: 43.01ms → 41.12ms (4%)
1 parent f9ecab5 commit 4da9c3e

1 file changed

Lines changed: 1 addition & 4 deletions

File tree

packages/@glimmer/syntax/lib/v2/normalize.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,7 @@ class ExpressionNormalizer {
267267
let namedLoc = this.block.loc(hash.loc);
268268
let argsLoc = SpanList.range([paramLoc, namedLoc]);
269269

270-
let positional = this.block.builder.positional(
271-
params.map((p) => this.normalize(p, ASTv2.STRICT_RESOLUTION)),
272-
paramLoc
273-
);
270+
let positional = this.block.builder.positional(paramList, paramLoc);
274271

275272
let named = this.block.builder.named(
276273
hash.pairs.map((p) => this.namedArgument(p)),

0 commit comments

Comments
 (0)