Skip to content

Commit c29e061

Browse files
committed
perf(concat-source): replace for-of in buffers() with indexed loops
Per-call iterator allocation for the outer `for (const child of this._children)` and the inner `for (const buffer of child.buffers())` shows up as ~40% of buffers() time on a nested 4x10 ConcatSource — the shape webpack produces during emit when wrapping module bodies. A/B/A median over 5 alternating wall-clock runs (es6-promise.js fixture, nested 4x10 raw): baseline: 659 075 ops/s this: 1 054 270 ops/s (+60%) Same V8 hot-path principle as the recent PrefixSource regex switch — the optimizer is much happier when array iteration stays integer- indexed and the array element type stays monomorphic. Index-based length hoisting (`childCount`, `blen`) keeps the bound check out of the loop body. Tests unchanged; full suite still green. https://claude.ai/code/session_01EHhGq9PRFRGefVtwwasCqZ
1 parent dac0eb8 commit c29e061

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

lib/ConcatSource.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,19 @@ class ConcatSource extends Source {
9797
*/
9898
buffers() {
9999
if (!this._isOptimized) this._optimize();
100+
const children = /** @type {SourceLike[]} */ (this._children);
101+
const childCount = children.length;
100102
/** @type {Buffer[]} */
101103
const buffers = [];
102-
for (const child of /** @type {SourceLike[]} */ (this._children)) {
104+
// Indexed loop + manual splat avoids the iterator allocation per
105+
// child and the inner for-of allocation per child.buffers() call.
106+
// Hot path during webpack's emit on deeply-nested ConcatSources.
107+
for (let ci = 0; ci < childCount; ci++) {
108+
const child = children[ci];
103109
if (typeof child.buffers === "function") {
104-
for (const buffer of child.buffers()) {
105-
buffers.push(buffer);
110+
const childBuffers = child.buffers();
111+
for (let bi = 0, blen = childBuffers.length; bi < blen; bi++) {
112+
buffers.push(childBuffers[bi]);
106113
}
107114
} else if (typeof child.buffer === "function") {
108115
buffers.push(child.buffer());

0 commit comments

Comments
 (0)