stream: reduce per-chunk work in WHATWG tee and BYOB reads - #64818
Open
mcollina wants to merge 2 commits into
Open
stream: reduce per-chunk work in WHATWG tee and BYOB reads#64818mcollina wants to merge 2 commits into
mcollina wants to merge 2 commits into
Conversation
The byte controller's [[pendingPullIntos]] list was still a plain array consumed with ArrayPrototypeShift, while every other per-chunk queue in the WHATWG streams implementation has moved to the Queue ring buffer. BYOB reads push and shift one descriptor per read, and Array.prototype shift has real per-call cost even at length 1. Back the descriptor list with the same lazily materialized Queue used for the request queues, so constructing a byte stream still allocates no descriptor storage. Signed-off-by: Matteo Collina <hello@matteocollina.com>
Both readableStreamDefaultTee and the byte tee's default-reader pull path allocated a fresh read request object (three closures) plus a fresh forwarding microtask closure for every chunk. Only one read is ever in flight per tee (guarded by the `reading` flag), so a single read request and forwarding function can be shared across all chunks, with the chunk handed over through a captured slot. Add a steady-state tee benchmark covering the default and byte paths. Signed-off-by: Matteo Collina <hello@matteocollina.com>
Collaborator
|
Review requested:
|
anonrig
approved these changes
Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two per-chunk reductions in the WHATWG streams implementation, continuing the series from #64431 / #64451.
1. Ring buffer for pending BYOB pull-into descriptors
The byte controller's
[[pendingPullIntos]]list was the last per-chunk queue still backed by a plain array consumed withArrayPrototypeShift. BYOB reads push and shift one descriptor per read, andArray.prototype.shifthas real per-call cost even at length 1. This backs the list with the same lazily materializedQueuering buffer used for the request queues in #64431, so constructing a byte stream still allocates no descriptor storage.2. Reused tee read request
Both
ReadableStreamDefaultTeeand the byte tee's default-reader pull path allocated a fresh read request object (three computed-symbol methods) plus a fresh forwarding microtask closure for every chunk. Only one read is ever in flight per tee (guarded by thereadingflag), so a single read request and forwarding function are now shared across all chunks, with the chunk handed over through a captured slot. The request is materialized lazily on the first pull sotee()itself stays allocation-light.A steady-state tee benchmark is added (
benchmark/webstreams/tee.js); tee previously only had creation coverage.Benchmarks (
benchmark/compare.js, 12–20 runs each, quiet machine):All other rows (readable-read normal, read-buffered, async-iterator, creation incl.
ReadableStream.tee, js_transfer) are neutral; the eager-request version of the tee change initially regressed tee creation by 24 % which is what motivated the lazy materialization (row now +0.49 % n.s.).Gates: WPT streams/compression/encoding plus the whatwg/webstreams parallel suites all pass. One white-box test that planted a plain array as
[[pendingPullIntos]]was updated to build the realQueuerepresentation.