Latest Results
perf: revert createInnerContext + findMatch changes — CodSpeed regressions
CodSpeed flagged three significant regressions:
cache-predicate -47.96%
exports-field -37.93%
main-files -23.74%
The common path across all three is `doResolve` → `createInnerContext`,
which I had refactored to take the outer context + stack + message
directly (avoiding the intermediate 6-field object literal). On paper
this saved one allocation per call; under cachegrind simulation the
extra polymorphic `outer.X` reads on the user-supplied resolveContext
appear to outweigh the saved allocation, regressing every benchmark
that goes through the resolve pipeline.
The exports-field regression also points at `findMatch`, where the
state-tracking refactor (precomputed `bestMatchPatternIndex` threaded
into `patternKeyCompare`, plus `bestMatchIsPattern`/`bestMatchIsSubpath`
to skip the two trailing `bestMatch.endsWith("/")` /
`bestMatch.includes("*")` scans) added per-iteration store overhead in
a measurably hot loop.
Revert both back to upstream shape:
- lib/createInnerContext.js + lib/Resolver.js doResolve: original
intermediate-object form.
- lib/util/entrypoints.js patternKeyCompare + findMatch: original
2-arg signature, `lastIndexOf("*")` confirmation, trailing
`endsWith`/`includes` scans, `key[len-1]` indexed access.
Kept (each one is either skipping a real call or eliminating real
work, with no per-call accounting risk):
- lib/util/path.js isSubPath — charCode-based last-char check,
skips `normalize()` on the common branch.
- lib/util/entrypoints.js conditionalMapping — local `top` reference
for the lookup-stack tip; saves two `lookup[lookup.length - 1]`
walks per iteration.
- lib/ExportsFieldPlugin.js / lib/ImportsFieldPlugin.js — hoist the
duplicate `relativePath.slice(2)` / `path_.slice(2)`.
- lib/ModulesUtils.js — nested `for` loops instead of
`.paths.map(...).reduce(spread)`; removes intermediate sub-arrays.
- lib/ParsePlugin.js — hoist `this.requestOptions` to a local.
- benchmark/cases/is-sub-path/ + test/path.test.js — micro-bench
and extended `isSubPath` coverage.
Full jest suite still passes (983 tests), lint clean.claude/search-perf-improvements-GXYWT perf: deeper hot-path cleanups surfaced by follow-up audit
Four targeted changes along the resolve pipeline, each keeping exact
existing behavior:
- lib/ModulesUtils.js: rebuild the addrs list with nested `for` loops
instead of `.paths.map(...).reduce((arr, sub) => (arr.push(...sub),
arr), [])`. The old shape allocated one intermediate sub-array per
ancestor path plus a reduce accumulator closure; the flat form
allocates exactly one array and pushes directly. Runs every time
`ModulesInHierarchicalDirectoriesPlugin` handles a bare request.
- lib/ParsePlugin.js: hoist `this.requestOptions` to a local before
the tap. Purely removes one `this`-chase per resolve step through
the parse hook. Kept the three-way spread — V8's
CopyDataProperties matches `Object.assign` under CodSpeed
simulation, so a swap would be a wash.
- lib/util/entrypoints.js patternKeyCompare / findMatch: pass the
pre-computed `patternIndex` (from the outer loop) into
`patternKeyCompare` instead of re-running `a.indexOf("*")` /
`b.indexOf("*")` on every comparison. `findMatch` also carries
`bestMatchPatternIndex` so the left-hand side skips the rescan too.
For fields with N keys this removes ~N extra `indexOf` scans per
match attempt.
- lib/AliasUtils.js aliasResolveHandler: hoist the
wildcard-prefix/suffix check plus the `innerRequest.slice(
item.name.length)` out of the per-alias `resolveWithAlias`
closure. Previously recomputed for every element of an array
alias (`{ alias: [preferred, fallback, …] }`); now computed once
per matched item.
Full jest suite still green (992 tests). Wall-clock benchmarks move
positively on the cases that touch these code paths
(exports-field/imports-field/exports-patterns-many, alias-realistic,
array-alias, prefer-relative, cache-predicate, resolve-to-context).claude/search-perf-improvements-GXYWT Latest Branches
-48%
claude/search-perf-improvements-GXYWT +15%
fix-use-basename-helper-everywhere 0%
claude/resolver-optional-context-JqGad © 2026 CodSpeed Technology