Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stream: replace queue and readRequests with buffer list for performance improvement #49554

Conversation

rluvaton
Copy link
Member

@rluvaton rluvaton commented Sep 8, 2023

webstream possible improvement:

BufferList implementation

00:24:29.343                                                                        confidence improvement accuracy (*)   (**)   (***)
00:24:29.343 webstreams/creation.js kind='ReadableStream' n=50000                                   1.04 %       ±3.94% ±5.25%  ±6.83%
00:24:29.343 webstreams/creation.js kind='TransformStream' n=50000                                  0.06 %       ±2.59% ±3.45%  ±4.52%
00:24:29.343 webstreams/creation.js kind='WritableStream' n=50000                                   0.19 %       ±4.60% ±6.12%  ±7.98%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=1024 n=100000                 1.58 %       ±4.24% ±5.64%  ±7.34%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=2048 n=100000                 1.13 %       ±4.28% ±5.69%  ±7.41%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=4096 n=100000                 1.50 %       ±4.50% ±5.99%  ±7.79%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=512 n=100000                  1.04 %       ±5.26% ±7.00%  ±9.12%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=1024 n=100000                 2.24 %       ±5.31% ±7.07%  ±9.20%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=2048 n=100000                 3.03 %       ±4.62% ±6.15%  ±8.00%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=4096 n=100000                 2.97 %       ±5.12% ±6.81%  ±8.86%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=512 n=100000                  3.92 %       ±4.65% ±6.19%  ±8.06%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=1024 n=100000                -0.04 %       ±4.14% ±5.50%  ±7.16%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=2048 n=100000                -1.05 %       ±4.87% ±6.48%  ±8.43%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=4096 n=100000                 2.22 %       ±4.57% ±6.07%  ±7.91%
00:24:29.343 webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=512 n=100000                 -2.14 %       ±4.71% ±6.27%  ±8.16%
00:24:29.344 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=1024 n=100000                  1.56 %       ±4.40% ±5.85%  ±7.62%
00:24:29.344 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=2048 n=100000                  0.54 %       ±4.56% ±6.06%  ±7.89%
00:24:29.344 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=4096 n=100000                  3.16 %       ±4.44% ±5.91%  ±7.70%
00:24:29.344 webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=512 n=100000                   0.90 %       ±4.70% ±6.26%  ±8.16%
00:24:29.344 webstreams/readable-async-iterator.js n=100000                                         0.03 %       ±7.40% ±9.84% ±12.81%
00:24:29.344 
00:24:29.344 Be aware that when doing many comparisons the risk of a false-positive
00:24:29.344 result increases. In this case, there are 20 comparisons, you can thus
00:24:29.344 expect the following amount of false-positive results:
00:24:29.344   1.00 false positives, when considering a   5% risk acceptance (*, **, ***),
00:24:29.344   0.20 false positives, when considering a   1% risk acceptance (**, ***),
00:24:29.344   0.02 false positives, when considering a 0.1% risk acceptance (***)

From my local tests:

Before

❯ ./node ./benchmark/webstreams/pipe-to.js
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=512 n=5000000: 1,073,259.5235043082
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=512 n=5000000: 1,112,582.388083188
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=512 n=5000000: 1,130,721.9334553012
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=512 n=5000000: 1,137,875.2107408328
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=1024 n=5000000: 1,145,415.4228369598
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=1024 n=5000000: 1,119,071.6166112064
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=1024 n=5000000: 1,112,401.620591177
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=1024 n=5000000: 1,122,177.222643778
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=2048 n=5000000: 1,154,120.0021085772
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=2048 n=5000000: 1,137,931.8271974607
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=2048 n=5000000: 1,150,085.2975136968
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=2048 n=5000000: 1,120,964.4298001872
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=4096 n=5000000: 1,126,744.873505527
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=4096 n=5000000: 1,148,843.5697545216
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=4096 n=5000000: 1,133,865.2778680783
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=4096 n=5000000: 1,132,648.4636818648

After

❯ ./node ./benchmark/webstreams/pipe-to.js
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=512 n=5000000: 1,191,920.5427624737
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=512 n=5000000: 1,199,980.044139869
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=512 n=5000000: 1,196,830.8757150145
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=512 n=5000000: 1,209,921.9163751516
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=1024 n=5000000: 1,199,785.7782492938
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=1024 n=5000000: 1,191,548.2411812833
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=1024 n=5000000: 1,205,993.3892632995
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=1024 n=5000000: 1,191,874.810445273
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=2048 n=5000000: 1,209,462.7154360572
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=2048 n=5000000: 1,187,768.408534668
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=2048 n=5000000: 1,195,187.8509158778
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=2048 n=5000000: 1,201,572.702366821
webstreams/pipe-to.js highWaterMarkW=512 highWaterMarkR=4096 n=5000000: 1,197,150.4825638772
webstreams/pipe-to.js highWaterMarkW=1024 highWaterMarkR=4096 n=5000000: 1,179,266.3281946357
webstreams/pipe-to.js highWaterMarkW=2048 highWaterMarkR=4096 n=5000000: 1,205,445.1767767125
webstreams/pipe-to.js highWaterMarkW=4096 highWaterMarkR=4096 n=5000000: 1,235,058.8880696953

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. web streams labels Sep 8, 2023
@rluvaton rluvaton force-pushed the improve-readable-stream-perf-by-moving-to-list branch from 8465d8b to 4a982c6 Compare September 8, 2023 12:15
@rluvaton rluvaton added performance Issues and PRs related to the performance of Node.js. needs-benchmark-ci PR that need a benchmark CI run. labels Sep 8, 2023
@rluvaton rluvaton changed the title stream: replace queue with buffer list for performance improvement stream: replace queue and readRequests with buffer list for performance improvement Sep 8, 2023
Copy link
Member

@ronag ronag left a comment

Choose a reason for hiding this comment

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

I think using FixedQueue would have better performance?

Comment on lines +3114 to +3116
// TODO - may be able to change this to next next next
while (reader[kState].readRequests.length > 0) {
// TODO - why this is in the while loop?
Copy link
Member Author

Choose a reason for hiding this comment

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

remove todos

@rluvaton
Copy link
Member Author

rluvaton commented Sep 8, 2023

Benchmark CI for BufferList implementation

https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1369/

@rluvaton rluvaton force-pushed the improve-readable-stream-perf-by-moving-to-list branch from 5943045 to 4e39d86 Compare September 8, 2023 13:59
@rluvaton
Copy link
Member Author

rluvaton commented Sep 8, 2023

the pipe-to benchmark takes too long, it's currently running for an hour.

Each iteration (single combination) takes 9 seconds. there are 16 possible combinations.
so 9 seconds * 16 combination * 30 runs * 2 versions = 2 hours and 24 minutes...

new Benchmark CI that has reduced the number of chunks from 5M to 100K for BufferList implementation
https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/1370/

Each iteration (single combination) takes 9 seconds. there are 16 possible combinations.
so 9 seconds * 16 combination * 30 runs * 2 versions = 2 hours and 24 minutes...
controller[kState].queueTotalSize = 0;
}

function peekQueueValue(controller) {
assert(controller[kState].queue !== undefined);
assert(controller[kState].queueTotalSize !== undefined);
assert(controller[kState].queue.length);
return controller[kState].queue[0].value;
debugger;
Copy link
Member Author

Choose a reason for hiding this comment

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

remove

@rluvaton
Copy link
Member Author

rluvaton commented Sep 8, 2023

I think using FixedQueue would have better performance?

Could not make it work, the tests failed for some reason...


current BufferList does not show any improvement so closing this

@rluvaton rluvaton closed this Sep 8, 2023
@rluvaton rluvaton deleted the improve-readable-stream-perf-by-moving-to-list branch September 8, 2023 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-benchmark-ci PR that need a benchmark CI run. needs-ci PRs that need a full CI run. performance Issues and PRs related to the performance of Node.js. web streams
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants