Skip to content

stream: cut per-chunk overhead in WHATWG streams#64252

Open
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:webstream-perf-round3
Open

stream: cut per-chunk overhead in WHATWG streams#64252
mcollina wants to merge 1 commit into
nodejs:mainfrom
mcollina:webstream-perf-round3

Conversation

@mcollina

@mcollina mcollina commented Jul 2, 2026

Copy link
Copy Markdown
Member

Consolidates the spec's per-chunk predicate chains into single passes over the controller/stream state, mirrors "close queued or in flight" as a boolean flag, and materializes the TransformStream [[backpressureChangePromise]] record lazily on first observation.

Benchmark results (benchmark/compare.js --runs 10 vs main, same-day build):

webstreams/pipe-to.js (all 16 hwm configs)                 ***  +16.6% .. +23.1%
webstreams/readable-read-buffered.js (all 4 sizes)         ***  +17.7% .. +23.5%
webstreams/readable-async-iterator.js n=100000             ***  +18.4%
webstreams/readable-read.js type='byob' n=100000           ***   +3.6%
webstreams/creation.js kind='TransformStream' n=50000      ***   +6.7%

No regressions on the remaining rows (n.s.). WPT streams/compression/encoding and all parallel whatwg/webstream tests pass unchanged.

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. web streams labels Jul 2, 2026
@mcollina mcollina requested a review from aduh95 July 2, 2026 08:27
Consolidate the spec's per-chunk predicate chains (CanCloseOrEnqueue,
IsLocked, HasDefaultReader, GetNumReadRequests, GetDesiredSize and the
writable-side equivalents) into single passes over the controller and
stream state, mirror "close queued or in flight" as a boolean flag
maintained at the few close-request transition sites, and materialize
the TransformStream [[backpressureChangePromise]] record lazily on
first observation so backpressure flips nobody is waiting on allocate
nothing.

Assisted-by: Claude Code
Signed-off-by: Matteo Collina <hello@matteocollina.com>
@mcollina mcollina force-pushed the webstream-perf-round3 branch from ef778b5 to ddba21e Compare July 2, 2026 08:35
@aduh95

aduh95 commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Benchmark CI: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1879/
Benchmark GHA: https://github.com/nodejs/node/actions/runs/28576859103

Results
                                                                       confidence improvement accuracy (*)   (**)  (***)
webstreams/creation.js kind='ReadableStream.tee' n=50000                              -0.07 %       ±0.51% ±0.68% ±0.89%
webstreams/creation.js kind='ReadableStream' n=50000                            *      5.00 %       ±4.75% ±6.33% ±8.23%
webstreams/creation.js kind='ReadableStreamBYOBReader' n=50000                         0.10 %       ±1.39% ±1.85% ±2.40%
webstreams/creation.js kind='ReadableStreamDefaultReader' n=50000                     -0.24 %       ±1.53% ±2.05% ±2.68%
webstreams/creation.js kind='TransformStream' n=50000                         ***     10.64 %       ±1.32% ±1.77% ±2.32%
webstreams/creation.js kind='WritableStream' n=50000                                   1.10 %       ±1.66% ±2.21% ±2.88%
webstreams/js_transfer.js n=10000 payload='ReadableStream'                             0.61 %       ±0.68% ±0.91% ±1.19%
webstreams/js_transfer.js n=10000 payload='TransformStream'                            0.28 %       ±0.42% ±0.56% ±0.74%
webstreams/js_transfer.js n=10000 payload='WritableStream'                             0.36 %       ±0.46% ±0.61% ±0.79%
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=1024 n=500000        ***     22.40 %       ±1.26% ±1.69% ±2.20%
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=2048 n=500000        ***     21.74 %       ±1.26% ±1.68% ±2.20%
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=4096 n=500000        ***     21.97 %       ±1.41% ±1.88% ±2.45%
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=512 n=500000         ***     21.75 %       ±1.45% ±1.93% ±2.52%
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=1024 n=500000        ***     20.77 %       ±0.96% ±1.28% ±1.67%
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=2048 n=500000        ***     21.73 %       ±1.19% ±1.58% ±2.05%
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=4096 n=500000        ***     20.86 %       ±1.14% ±1.52% ±1.99%
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=512 n=500000         ***     22.52 %       ±1.47% ±1.95% ±2.55%
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=1024 n=500000        ***     21.78 %       ±1.48% ±1.96% ±2.56%
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=2048 n=500000        ***     21.54 %       ±1.50% ±2.00% ±2.60%
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=4096 n=500000        ***     21.30 %       ±1.42% ±1.89% ±2.47%
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=512 n=500000         ***     22.06 %       ±1.34% ±1.79% ±2.33%
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=1024 n=500000         ***     20.39 %       ±1.03% ±1.37% ±1.78%
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=2048 n=500000         ***     22.06 %       ±1.46% ±1.95% ±2.54%
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=4096 n=500000         ***     21.28 %       ±1.56% ±2.07% ±2.70%
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=512 n=500000          ***     23.02 %       ±1.38% ±1.84% ±2.40%
webstreams/readable-async-iterator.js n=100000                                ***     20.85 %       ±3.71% ±4.99% ±6.58%
webstreams/readable-read-buffered.js bufferSize=1 n=100000                    ***     19.68 %       ±2.72% ±3.62% ±4.71%
webstreams/readable-read-buffered.js bufferSize=10 n=100000                   ***     21.95 %       ±4.79% ±6.39% ±8.35%
webstreams/readable-read-buffered.js bufferSize=100 n=100000                  ***     15.02 %       ±4.16% ±5.56% ±7.27%
webstreams/readable-read-buffered.js bufferSize=1000 n=100000                 ***     20.77 %       ±3.95% ±5.29% ±6.94%
webstreams/readable-read.js type='byob' n=100000                              ***      2.41 %       ±1.17% ±1.56% ±2.03%
webstreams/readable-read.js type='normal' n=100000                            ***     16.87 %       ±2.32% ±3.09% ±4.02%

Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 32 comparisons, you can thus
expect the following amount of false-positive results:
  1.60 false positives, when considering a   5% risk acceptance (*, **, ***),
  0.32 false positives, when considering a   1% risk acceptance (**, ***),
  0.03 false positives, when considering a 0.1% risk acceptance (***)

@aduh95 aduh95 added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Jul 2, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jul 2, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

This comment was marked as duplicate.

@aduh95 aduh95 added the commit-queue Add this label to land a pull request using GitHub Actions. label Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue Add this label to land a pull request using GitHub Actions. needs-ci PRs that need a full CI run. web streams

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants