Skip to content

stream: improve ReadableStream.tee perf by remove ReflectConstruct usage - #49546

Merged
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
rluvaton:add-benchmark-and-improve-webstream-creation-perf
Sep 11, 2023
Merged

stream: improve ReadableStream.tee perf by remove ReflectConstruct usage#49546
nodejs-github-bot merged 1 commit into
nodejs:mainfrom
rluvaton:add-benchmark-and-improve-webstream-creation-perf

Conversation

@rluvaton

@rluvatonrluvaton commented Sep 7, 2023

Copy link
Copy Markdown
Member

also added more webstream creation benchmarks

My local benchmark shows improvement of 2 times:

After:

webstreams/creation.js kind="ReadableStream.tee" n=50000: 126,685.06978447069 # Before
webstreams/creation.js kind="ReadableStream.tee" n=50000: 242,524.97642257062 # After

Benchmark CI output:

00:22:52.357 ++ Rscript benchmark/compare.R
00:22:53.287 confidence improvement accuracy (*) (**) (***)
00:22:53.287 webstreams/creation.js kind='ReadableStream.tee' n=50000 *** 86.53 % ±3.55% ±4.75% ±6.24%
00:22:53.287 webstreams/creation.js kind='ReadableStream' n=50000 1.83 % ±3.38% ±4.50% ±5.86%
00:22:53.287 webstreams/creation.js kind='ReadableStreamBYOBReader' n=50000 -0.23 % ±3.61% ±4.81% ±6.26%
00:22:53.287 webstreams/creation.js kind='ReadableStreamDefaultReader' n=50000 9.73 % ±11.91% ±15.87% ±20.70%
00:22:53.287 webstreams/creation.js kind='TransformStream' n=50000 0.96 % ±2.82% ±3.75% ±4.89%
00:22:53.287 webstreams/creation.js kind='WritableStream' n=50000 -1.19 % ±4.27% ±5.68% ±7.40%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=1024 n=5000000 -0.19 % ±4.53% ±6.03% ±7.86%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=2048 n=5000000 -3.72 % ±4.90% ±6.53% ±8.53%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=4096 n=5000000 2.64 % ±3.81% ±5.07% ±6.60%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=512 n=5000000 3.33 % ±4.26% ±5.70% ±7.49%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=1024 n=5000000 0.78 % ±4.03% ±5.36% ±6.98%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=2048 n=5000000 -1.02 % ±3.54% ±4.71% ±6.14%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=4096 n=5000000 -4.02 % ±4.44% ±5.93% ±7.75%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=512 n=5000000 -2.21 % ±3.80% ±5.06% ±6.60%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=1024 n=5000000 -1.65 % ±3.45% ±4.59% ±5.98%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=2048 n=5000000 -1.65 % ±3.83% ±5.11% ±6.66%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=4096 n=5000000 1.25 % ±3.83% ±5.10% ±6.64%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=512 n=5000000 -1.78 % ±4.88% ±6.50% ±8.46%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=1024 n=5000000 3.39 % ±5.70% ±7.58% ±9.87%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=2048 n=5000000 -2.18 % ±5.81% ±7.74% ±10.11%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=4096 n=5000000 -1.72 % ±3.33% ±4.43% ±5.77%
00:22:53.287 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=512 n=5000000 1.77 % ±4.47% ±5.96% ±7.77%
00:22:53.382 webstreams/readable-async-iterator.js n=100000 1.66 % ±7.72% ±10.27% ±13.36%
00:22:53.383 00:22:53.383 Be aware that when doing many comparisons the risk of a false-positive
00:22:53.383 result increases. In this case, there are 23 comparisons, you can thus
00:22:53.383 expect the following amount of false-positive results:
00:22:53.383 1.15 false positives, when considering a 5% risk acceptance (*, **, ***),
00:22:53.383 0.23 false positives, when considering a 1% risk acceptance (**, ***),
00:22:53.383 0.02 false positives, when considering a 0.1% risk acceptance (***)

also added more webstream creation benchmarks
@nodejs-github-botnodejs-github-bot added needs-ci PRs that need a full CI run. web streams labels Sep 7, 2023
@rluvatonrluvaton added needs-benchmark-ci PR that need a benchmark CI run. request-ci Add this label to start a Jenkins CI on a PR. labels Sep 7, 2023
Comment on lines +1234 to +1235
// For spec compliance the Tee must be a ReadableStream
tee.constructor = ReadableStream;

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Otherwise, the wpt tee test fails:

test(()=>{
constrs=newReadableStream();
constresult=rs.tee();
assert_true(Array.isArray(result),'return value should be an array');
assert_equals(result.length,2,'array should have length 2');
assert_equals(result[0].constructor,ReadableStream,'0th element should be a ReadableStream');
assert_equals(result[1].constructor,ReadableStream,'1st element should be a ReadableStream');
},'ReadableStream teeing: rs.tee() returns an array of two ReadableStreams');

And the spec says

Tees this readable stream, returning a two-element array containing the two resulting branches as new ReadableStream instances.

From the Spec

@ExE-BossExE-BossJul 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A better option would’ve been to do:

TeeReadableStream.prototype=ReadableStream.prototype;

Or at least:

deleteTeeReadableStream.prototype.constructor;

@rluvaton

Copy link
Copy Markdown
MemberAuthor

@github-actionsgithub-actionsBot removed the request-ci Add this label to start a Jenkins CI on a PR. label Sep 7, 2023
@rluvatonrluvaton added benchmark Issues and PRs related to the benchmark subsystem. request-ci Add this label to start a Jenkins CI on a PR. labels Sep 7, 2023
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@github-actionsgithub-actionsBot removed the request-ci Add this label to start a Jenkins CI on a PR. label Sep 7, 2023
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@rluvatonrluvaton added the performance Issues and PRs related to the performance of Node.js. label Sep 7, 2023

@anonriganonrig 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.

You beat me to it. Good work!

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@anonriganonrig added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Sep 8, 2023
[SymbolToStringTag]: getNonWritablePropertyDescriptor(ReadableByteStreamController.name),
});

function TeeReadableStream(start, pull, cancel) {

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.

is there a reason this can't be a normal class? Would help with the inheritance/prototype hacks needed

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

I'll have to call super and the original implementation don't call the constructor

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.

I think it would simplify the code significantly, not blocking or anything

@rluvatonrluvatonSep 10, 2023

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

so you mean to just convert it to class with extends but without super?

when I do the WPT tests fails so keeping it as is

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@mcollinamcollina 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.

lgtm

@rluvatonrluvaton added the commit-queue Add this label to land a pull request using GitHub Actions. label Sep 11, 2023
@nodejs-github-botnodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Sep 11, 2023
@nodejs-github-bot
nodejs-github-bot merged commit a7fe8b0 into nodejs:mainSep 11, 2023
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Landed in a7fe8b0

@rluvaton
rluvaton deleted the add-benchmark-and-improve-webstream-creation-perf branch September 11, 2023 07:52
@rluvatonrluvaton mentioned this pull request Sep 11, 2023
rluvaton added a commit to rluvaton/node that referenced this pull request Sep 12, 2023
also added more webstream creation benchmarks
PR-URL: nodejs#49546
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
UlisesGascon pushed a commit that referenced this pull request Sep 13, 2023
also added more webstream creation benchmarks
PR-URL: #49546
Backport-PR-URL: #49620
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.benchmarkIssues and PRs related to the benchmark subsystem.needs-benchmark-ciPR that need a benchmark CI run.needs-ciPRs that need a full CI run.performanceIssues and PRs related to the performance of Node.js.web streams

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants

@rluvaton@nodejs-github-bot@mcollina@anonrig@ExE-Boss@KhafraDev@targos