FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

stream: fast-path stateless transform flush results by trivikr · Pull Request #63605 · nodejs/node · GitHub

/ node Public

stream: fast-path stateless transform flush results - #63605

Merged
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
trivikr:stream-iter-pull-fast-path-stateless-transform-results
Jun 4, 2026
Merged

stream: fast-path stateless transform flush results#63605
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
trivikr:stream-iter-pull-fast-path-stateless-transform-results

Conversation

trivikr commented May 28, 2026

Copy link
Copy Markdown
Member

Optimize stream/iter stateless transform flush handling by
fast-pathing common flush result shapes.

This avoids generator-based normalization for already-normalized
batches and primitive byte outputs while preserving the corrected
flush ordering behavior.

Tested using temporary benchmark specific to the change

Benchmark code
// Measures stream/iter stateless transform flush-result normalization.
// Uses many tiny pipelines so flush overhead is not hidden by chunk throughput.
'use strict';

const common = require('../common.js');

const bench = common.createBenchmark(main, {
  api: ['iter', 'iter-sync'],
  result: ['null', 'batch', 'uint8array', 'string', 'arraybuffer', 'dataview'],
  transforms: [1, 4],
  n: [100000],
}, {
  flags: ['--experimental-stream-iter'],
  test: {
    api: 'iter',
    result: 'batch',
    transforms: 1,
    n: 1,
  },
});

function getFlushResult(result, chunk) {
  switch (result) {
    case 'null':
      return null;
    case 'batch':
      return [chunk];
    case 'uint8array':
      return chunk;
    case 'string':
      return 'abcd';
    case 'arraybuffer':
      return chunk.buffer;
    case 'dataview':
      return new DataView(chunk.buffer);
  }
}

function createTransforms(count, result, chunk) {
  return Array.from({ length: count }, () => {
    return (chunks) => chunks === null ? getFlushResult(result, chunk) : null;
  });
}

function main({ api, result, transforms, n }) {
  const chunk = new Uint8Array(4);
  const fns = createTransforms(transforms, result, chunk);

  switch (api) {
    case 'iter':
      return benchIter(fns, n);
    case 'iter-sync':
      return benchIterSync(fns, n);
  }
}

function benchIter(fns, n) {
  const { pipeTo } = require('stream/iter');
  const writer = {
    write() {},
    writeSync() { return true; },
    endSync() { return 1; },
  };

  (async () => {
    bench.start();
    for (let i = 0; i < n; i++) {
      await pipeTo([], ...fns, writer);
    }
    bench.end(n);
  })();
}

function benchIterSync(fns, n) {
  const { pipeToSync } = require('stream/iter');
  const writer = {
    writeSync() {},
    endSync() { return 1; },
  };

  bench.start();
  for (let i = 0; i < n; i++) {
    pipeToSync([], ...fns, writer);
  }
  bench.end(n);
}
Benchmark results
                                                                                           confidence improvement accuracy (*)   (**)  (***)
streams/iter-transform-flush.js n=100000 transforms=1 result='arraybuffer' api='iter-sync'        ***      6.47 %       ±1.18% ±1.56% ±2.04%
streams/iter-transform-flush.js n=100000 transforms=1 result='arraybuffer' api='iter'             ***     16.53 %       ±0.67% ±0.88% ±1.15%
streams/iter-transform-flush.js n=100000 transforms=1 result='batch' api='iter-sync'              ***      9.53 %       ±0.78% ±1.04% ±1.36%
streams/iter-transform-flush.js n=100000 transforms=1 result='batch' api='iter'                   ***     16.37 %       ±0.77% ±1.03% ±1.34%
streams/iter-transform-flush.js n=100000 transforms=1 result='dataview' api='iter-sync'            **      4.67 %       ±2.85% ±3.80% ±4.97%
streams/iter-transform-flush.js n=100000 transforms=1 result='dataview' api='iter'                ***     14.95 %       ±0.69% ±0.92% ±1.19%
streams/iter-transform-flush.js n=100000 transforms=1 result='null' api='iter-sync'               ***      4.62 %       ±1.01% ±1.35% ±1.76%
streams/iter-transform-flush.js n=100000 transforms=1 result='null' api='iter'                    ***     12.61 %       ±1.45% ±1.93% ±2.51%
streams/iter-transform-flush.js n=100000 transforms=1 result='string' api='iter-sync'             ***      6.24 %       ±2.00% ±2.68% ±3.52%
streams/iter-transform-flush.js n=100000 transforms=1 result='string' api='iter'                  ***     12.72 %       ±0.99% ±1.32% ±1.72%
streams/iter-transform-flush.js n=100000 transforms=1 result='uint8array' api='iter-sync'         ***      8.14 %       ±1.66% ±2.21% ±2.90%
streams/iter-transform-flush.js n=100000 transforms=1 result='uint8array' api='iter'              ***     15.46 %       ±1.24% ±1.66% ±2.19%
streams/iter-transform-flush.js n=100000 transforms=4 result='arraybuffer' api='iter-sync'        ***     23.47 %       ±2.41% ±3.22% ±4.21%
streams/iter-transform-flush.js n=100000 transforms=4 result='arraybuffer' api='iter'             ***     62.28 %       ±0.68% ±0.90% ±1.18%
streams/iter-transform-flush.js n=100000 transforms=4 result='batch' api='iter-sync'              ***     27.17 %       ±0.95% ±1.27% ±1.66%
streams/iter-transform-flush.js n=100000 transforms=4 result='batch' api='iter'                   ***     66.62 %       ±1.09% ±1.45% ±1.90%
streams/iter-transform-flush.js n=100000 transforms=4 result='dataview' api='iter-sync'           ***     19.41 %       ±1.93% ±2.58% ±3.36%
streams/iter-transform-flush.js n=100000 transforms=4 result='dataview' api='iter'                ***     56.88 %       ±0.80% ±1.07% ±1.41%
streams/iter-transform-flush.js n=100000 transforms=4 result='null' api='iter-sync'               ***     18.02 %       ±1.16% ±1.56% ±2.04%
streams/iter-transform-flush.js n=100000 transforms=4 result='null' api='iter'                    ***     37.92 %       ±2.02% ±2.70% ±3.54%
streams/iter-transform-flush.js n=100000 transforms=4 result='string' api='iter-sync'             ***     16.86 %       ±1.78% ±2.37% ±3.09%
streams/iter-transform-flush.js n=100000 transforms=4 result='string' api='iter'                  ***     44.45 %       ±0.83% ±1.11% ±1.45%
streams/iter-transform-flush.js n=100000 transforms=4 result='uint8array' api='iter-sync'         ***     26.73 %       ±2.91% ±3.90% ±5.15%
streams/iter-transform-flush.js n=100000 transforms=4 result='uint8array' api='iter'              ***     63.87 %       ±2.34% ±3.15% ±4.17%

Assisted-by: openai:gpt-5.5

Avoid generator-based normalization for common flush result types in
fused stateless stream/iter transforms. This keeps the corrected flush
ordering while reducing overhead for already-normalized batches and
primitive byte outputs.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/streams

nodejs-github-bot added needs-ci PRs that need a full CI run. stream Issues and PRs related to the stream subsystem. labels May 28, 2026

codecov Bot commented May 28, 2026
edited
Loading

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.06250% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.28%. Comparing base (4639dcb) to head (93eaa9a).
⚠️ Report is 70 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/streams/iter/pull.js 64.06% 21 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #63605      +/-   ##
==========================================
- Coverage   90.29%   90.28%   -0.02%     
==========================================
  Files         730      730              
  Lines      234695   234755      +60     
  Branches    43956    43967      +11     
==========================================
+ Hits       211927   211942      +15     
- Misses      14494    14546      +52     
+ Partials     8274     8267       -7     
Files with missing lines Coverage Δ
lib/internal/streams/iter/pull.js 83.62% <64.06%> (-4.50%) ⬇️

... and 23 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

trivikr added the request-ci Add this label to start a Jenkins CI on a PR. label May 29, 2026

mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

lgtm

github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 1, 2026

This comment was marked as outdated.

trivikr added the author ready PRs that have at least one approval, no outstanding review comments, and a CI started. label Jun 1, 2026

Copy link
Copy Markdown
Collaborator

trivikr added the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 4, 2026
nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Jun 4, 2026
nodejs-github-bot merged commit 5f727fd into nodejs:main Jun 4, 2026
86 checks passed

Copy link
Copy Markdown
Collaborator

Landed in 5f727fd

trivikr deleted the stream-iter-pull-fast-path-stateless-transform-results branch June 4, 2026 06:06
aduh95 pushed a commit that referenced this pull request Jun 18, 2026
Avoid generator-based normalization for common flush result types in
fused stateless stream/iter transforms. This keeps the corrected flush
ordering while reducing overhead for already-normalized batches and
primitive byte outputs.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: #63605
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
aduh95 pushed a commit to aduh95/node that referenced this pull request Jul 30, 2026
Avoid generator-based normalization for common flush result types in
fused stateless stream/iter transforms. This keeps the corrected flush
ordering while reducing overhead for already-normalized batches and
primitive byte outputs.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: nodejs#63605
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
aduh95 pushed a commit that referenced this pull request Aug 6, 2026
Avoid generator-based normalization for common flush result types in
fused stateless stream/iter transforms. This keeps the corrected flush
ordering while reducing overhead for already-normalized batches and
primitive byte outputs.

Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com>
Assisted-by: openai:gpt-5.5
PR-URL: #63605
Backport-PR-URL: #64675
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
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

Labels

author ready PRs that have at least one approval, no outstanding review comments, and a CI started. needs-ci PRs that need a full CI run. stream Issues and PRs related to the stream subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants


Back | FazBrowse Home | New Git URL