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>
PR-URL: https://github.com/nodejs/node/pull/64818
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Aviv Keller <me@aviv.sh>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Pure-JavaScript optimizations to lib/internal/webstreams/* that reduce
per-chunk and per-construction allocations on hot paths without
observable behavior change.
Per-chunk: reuse promise-reaction closures per controller, add buffered
fast path for async iterator, specialize callback wrappers by arity,
and share immutable nil records for writable stream resets.
Per-construction: use queueMicrotask for non-object start results,
materialize reader/writer .closed and .ready records lazily, and remove
dead allocations.
Assisted-by: Claude Fable 5
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/63876
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Mattias Buelens <mattias@buelens.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Add internal fast paths to improve webstreams performance without
changing the public API or breaking spec compliance.
1. ReadableStreamDefaultReader.read() fast path:
When data is already buffered in the controller's queue, return
PromiseResolve() directly without creating a DefaultReadRequest
object. This is spec-compliant because read() returns a Promise,
and resolved promises still run callbacks in the microtask queue.
2. pipeTo() batch read fast path:
When data is buffered, batch reads directly from the controller
queue up to highWaterMark without creating
PipeToReadableStreamReadRequest objects per chunk. Respects
backpressure by checking desiredSize after each write.
Benchmark results:
- pipeTo: ~11% faster (***)
- buffered read(): ~17-20% faster (***)
Co-Authored-By: Malte Ubl <malte@vercel.com>
PR-URL: https://github.com/nodejs/node/pull/61807
Reviewed-By: Stephen Belanger <admin@stephenbelanger.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>