perf: optimize deterministicGrouping and cached comparators on large builds#21197
Conversation
- deterministicGrouping: iterate size records with for-in instead of Object.keys (avoids per-call array allocation on the SplitChunks hot path) and let sumSize take a start index instead of slicing. - createCachedParameterizedComparator: return an arrow closure instead of a bound function; arrows dispatch faster on the sort hot path.
🦋 Changeset detectedLatest commit: 506219b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (0db8bbb). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@0db8bbb
yarn add -D webpack@https://pkg.pr.new/webpack@0db8bbb
pnpm add -D webpack@https://pkg.pr.new/webpack@0db8bbb |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #21197 +/- ##
=======================================
Coverage 92.70% 92.71%
=======================================
Files 588 588
Lines 64118 64118
Branches 17797 17798 +1
=======================================
+ Hits 59440 59444 +4
+ Misses 4678 4674 -4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will improve performance by 80.21%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ⚡ | Memory | benchmark "asset-modules-inline", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
1,293.6 KB | 317.6 KB | ×4.1 |
| ⚡ | Memory | benchmark "side-effects-reexport", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
1,208.6 KB | 768.1 KB | +57.35% |
| ⚡ | Memory | benchmark "asset-modules-bytes", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
326.8 KB | 245.7 KB | +32.97% |
| ⚡ | Memory | benchmark "devtool-source-map", scenario '{"name":"mode-production","mode":"production"}' |
7.7 MB | 6.3 MB | +23.74% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing perf/deterministic-grouping-comparators (506219b) with main (8596a28)
Summary
Two small, benchmarked hot-path optimizations (the safe subset salvaged from the now-closed #21192, which as a whole regressed CI benchmarks):
deterministicGrouping(SplitChunksmaxSize): iterate size records withfor..ininstead ofObject.keysto avoid a per-call array allocation, and givesumSizeastartindex instead ofslice()ing the node array.createCachedParameterizedComparator: return an arrow closure instead of a bound function — arrows dispatch faster on the sort hot path and the result is cached either way.Local micro-benchmarks:
deterministicGroupingover 3k items ~378ms → ~295ms (~22% faster); the cached comparator dispatch ~9% faster (arrow vsbind). Behavior is unchanged.What kind of change does this PR introduce?
perf
Did you add tests for your changes?
No new tests — behavior is unchanged and covered by existing
test/deterministicGrouping.unittest.js,StatsTestCases(131), and thesplit-chunksconfig cases (160, incl.max-size), all passing.Does this PR introduce a breaking change?
No.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
AI (Claude) was used to review #21192, isolate which of its changes were both safe and measurable wins, apply that subset, and run the before/after micro-benchmarks. The semantics-changing parts of #21192 (the
compareNumberstype-guard removal andconcatComparatorscache removal) were deliberately excluded.Generated by Claude Code