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

events: improve events performance by rluvaton · Pull Request #50422 · nodejs/node · GitHub

/ node Public

events: improve events performance - #50422

Closed
rluvaton wants to merge 3 commits into
nodejs:mainfrom
rluvaton:improve-ee-creation
Closed

events: improve events performance#50422
rluvaton wants to merge 3 commits into
nodejs:mainfrom
rluvaton:improve-ee-creation

Conversation

rluvaton commented Oct 27, 2023
edited
Loading

Copy link
Copy Markdown
Member

Benchmarks

Change _events to be a Map:

commit: 249c2b8

Notes:

  • I'm afraid this can break userland implementation of EventEmitter that are using node EventEmitter class functions (cc @ronag )
  • This also improves creation by a lot (and therefore improves streams creation)

Benchmark URL

15:31:01                                                                  confidence improvement accuracy (*)    (**)   (***)
15:31:01 events/ee-add-remove.js n=1000000 removeListener=0 newListener=0        ***     19.64 %       ±1.57%  ±2.09%  ±2.73%
15:31:01 events/ee-add-remove.js n=1000000 removeListener=0 newListener=1        ***     46.84 %       ±2.02%  ±2.70%  ±3.54%
15:31:01 events/ee-add-remove.js n=1000000 removeListener=1 newListener=0        ***     45.01 %       ±2.68%  ±3.60%  ±4.75%
15:31:01 events/ee-add-remove.js n=1000000 removeListener=1 newListener=1        ***     56.27 %       ±2.72%  ±3.64%  ±4.79%
15:31:01 events/ee-emit.js listeners=1 argc=0 n=2000000                          ***     32.42 %       ±9.82% ±13.07% ±17.02%
15:31:01 events/ee-emit.js listeners=1 argc=10 n=2000000                         ***     36.00 %       ±8.08% ±10.75% ±14.00%
15:31:01 events/ee-emit.js listeners=1 argc=2 n=2000000                          ***     23.57 %       ±9.57% ±12.75% ±16.62%
15:31:01 events/ee-emit.js listeners=1 argc=4 n=2000000                          ***     28.33 %       ±8.95% ±11.92% ±15.52%
15:31:01 events/ee-emit.js listeners=10 argc=0 n=2000000                                  4.48 %       ±7.03%  ±9.35% ±12.17%
15:31:01 events/ee-emit.js listeners=10 argc=10 n=2000000                                 0.02 %       ±4.28%  ±5.70%  ±7.42%
15:31:01 events/ee-emit.js listeners=10 argc=2 n=2000000                          **     -6.22 %       ±4.54%  ±6.06%  ±7.91%
15:31:01 events/ee-emit.js listeners=10 argc=4 n=2000000                          **      6.55 %       ±4.59%  ±6.13%  ±8.00%
15:31:01 events/ee-emit.js listeners=5 argc=0 n=2000000                                   1.39 %       ±9.30% ±12.37% ±16.11%
15:31:01 events/ee-emit.js listeners=5 argc=10 n=2000000                                 -0.34 %       ±7.02%  ±9.35% ±12.18%
15:31:01 events/ee-emit.js listeners=5 argc=2 n=2000000                                   5.45 %       ±8.85% ±11.78% ±15.33%
15:31:01 events/ee-emit.js listeners=5 argc=4 n=2000000                                   0.79 %       ±8.60% ±11.44% ±14.89%
15:31:01 events/ee-listen-unique.js n=1000000 events=1                           ***     30.56 %       ±2.05%  ±2.73%  ±3.56%
15:31:01 events/ee-listen-unique.js n=1000000 events=10                          ***     13.34 %       ±1.21%  ±1.62%  ±2.11%
15:31:01 events/ee-listen-unique.js n=1000000 events=2                           ***     18.32 %       ±1.99%  ±2.67%  ±3.51%
15:31:01 events/ee-listen-unique.js n=1000000 events=20                          ***     13.37 %       ±1.22%  ±1.62%  ±2.12%
15:31:01 events/ee-listen-unique.js n=1000000 events=3                           ***     19.46 %       ±1.15%  ±1.53%  ±2.00%
15:31:01 events/ee-listen-unique.js n=1000000 events=5                           ***     15.05 %       ±1.35%  ±1.80%  ±2.35%
15:31:01 events/ee-listener-count-on-prototype.js n=50000000                     ***     29.98 %       ±5.74%  ±7.70% ±10.14%
15:31:01 events/ee-listeners.js raw='false' listeners=5 n=5000000                        -2.69 %       ±7.61% ±10.13% ±13.18%
15:31:01 events/ee-listeners.js raw='false' listeners=50 n=5000000                        0.48 %       ±1.82%  ±2.42%  ±3.15%
15:31:01 events/ee-listeners.js raw='true' listeners=5 n=5000000                          6.34 %       ±8.35% ±11.12% ±14.49%
15:31:01 events/ee-listeners.js raw='true' listeners=50 n=5000000                        -1.34 %       ±4.45%  ±5.92%  ±7.71%
15:31:01 events/ee-once.js argc=0 n=20000000                                     ***     31.26 %       ±1.10%  ±1.47%  ±1.94%
15:31:01 events/ee-once.js argc=1 n=20000000                                     ***     26.62 %       ±0.60%  ±0.80%  ±1.04%
15:31:01 events/ee-once.js argc=4 n=20000000                                     ***     26.93 %       ±0.65%  ±0.86%  ±1.12%
15:31:01 events/ee-once.js argc=5 n=20000000                                     ***     27.19 %       ±0.76%  ±1.02%  ±1.32%
15:31:01 events/eventtarget-add-remove.js nListener=10 n=1000000                 ***      0.92 %       ±0.38%  ±0.51%  ±0.66%
15:31:01 events/eventtarget-add-remove.js nListener=5 n=1000000                    *      0.87 %       ±0.69%  ±0.91%  ±1.19%
15:31:01 events/eventtarget-creation.js n=1000000                                         0.60 %       ±5.04%  ±6.70%  ±8.73%
15:31:01 events/eventtarget.js listeners=1 n=1000000                                      0.90 %       ±6.28%  ±8.35% ±10.87%
15:31:01 events/eventtarget.js listeners=10 n=1000000                                     0.45 %       ±3.51%  ±4.68%  ±6.09%
15:31:01 events/eventtarget.js listeners=5 n=1000000                                      0.21 %       ±4.80%  ±6.39%  ±8.31%
15:31:01 
15:31:01 Be aware that when doing many comparisons the risk of a false-positive
15:31:01 result increases. In this case, there are 37 comparisons, you can thus
15:31:01 expect the following amount of false-positive results:
15:31:01   1.85 false positives, when considering a   5% risk acceptance (*, **, ***),
15:31:01   0.37 false positives, when considering a   1% risk acceptance (**, ***),
15:31:01   0.04 false positives, when considering a 0.1% risk acceptance (***)

I run it on streams as well to see the impact as this was my original intent: url

Change to Map todos:

  • move all our internal code away from _events and use [kEvents] instead
  • I saw undici used _events so need to migrate as well
change _events to be without __proto__: null

change _events to be without __proto__: null

Commit: eb29e97

I think the performance without proto is not fully representative as the event name can be anything so the dictionary mode is not used here

Benchmark URL

12:55:39 ++ Rscript benchmark/compare.R
12:55:40                                                                  confidence improvement accuracy (*)    (**)   (***)
12:55:40 events/ee-add-remove.js n=1000000 removeListener=0 newListener=0         **     -2.22 %       ±1.50%  ±2.00%  ±2.60%
12:55:40 events/ee-add-remove.js n=1000000 removeListener=0 newListener=1        ***     30.34 %       ±1.75%  ±2.33%  ±3.04%
12:55:40 events/ee-add-remove.js n=1000000 removeListener=1 newListener=0        ***     22.74 %       ±1.17%  ±1.56%  ±2.03%
12:55:40 events/ee-add-remove.js n=1000000 removeListener=1 newListener=1        ***     10.04 %       ±1.11%  ±1.47%  ±1.92%
12:55:40 events/ee-emit.js listeners=1 argc=0 n=2000000                          ***    159.54 %       ±8.72% ±11.64% ±15.20%
12:55:40 events/ee-emit.js listeners=1 argc=10 n=2000000                         ***    139.14 %      ±12.44% ±16.59% ±21.66%
12:55:40 events/ee-emit.js listeners=1 argc=2 n=2000000                          ***    159.56 %      ±13.83% ±18.46% ±24.15%
12:55:40 events/ee-emit.js listeners=1 argc=4 n=2000000                          ***    148.52 %      ±10.04% ±13.37% ±17.43%
12:55:40 events/ee-emit.js listeners=10 argc=0 n=2000000                         ***     13.34 %       ±7.48%  ±9.96% ±12.96%
12:55:40 events/ee-emit.js listeners=10 argc=10 n=2000000                        ***     11.22 %       ±5.66%  ±7.53%  ±9.81%
12:55:40 events/ee-emit.js listeners=10 argc=2 n=2000000                                  3.11 %       ±6.21%  ±8.27% ±10.77%
12:55:40 events/ee-emit.js listeners=10 argc=4 n=2000000                         ***     12.07 %       ±6.04%  ±8.04% ±10.47%
12:55:40 events/ee-emit.js listeners=5 argc=0 n=2000000                          ***     20.76 %       ±9.34% ±12.44% ±16.24%
12:55:40 events/ee-emit.js listeners=5 argc=10 n=2000000                         ***     17.29 %       ±8.71% ±11.59% ±15.10%
12:55:40 events/ee-emit.js listeners=5 argc=2 n=2000000                            *     13.10 %       ±9.93% ±13.21% ±17.20%
12:55:40 events/ee-emit.js listeners=5 argc=4 n=2000000                            *      9.82 %       ±9.51% ±12.66% ±16.48%
12:55:40 events/ee-listen-unique.js n=1000000 events=1                                    0.24 %       ±1.32%  ±1.76%  ±2.29%
12:55:40 events/ee-listen-unique.js n=1000000 events=10                          ***     -3.02 %       ±1.08%  ±1.44%  ±1.88%
12:55:40 events/ee-listen-unique.js n=1000000 events=2                           ***     -2.28 %       ±0.69%  ±0.92%  ±1.20%
12:55:40 events/ee-listen-unique.js n=1000000 events=20                           **     -2.16 %       ±1.56%  ±2.09%  ±2.73%
12:55:40 events/ee-listen-unique.js n=1000000 events=3                           ***     -2.03 %       ±0.98%  ±1.31%  ±1.71%
12:55:40 events/ee-listen-unique.js n=1000000 events=5                           ***     -4.36 %       ±0.89%  ±1.19%  ±1.55%
12:55:40 events/ee-listener-count-on-prototype.js n=50000000                     ***     -6.40 %       ±3.40%  ±4.53%  ±5.91%
12:55:40 events/ee-listeners.js raw='false' listeners=5 n=5000000                  *     -8.30 %       ±6.34%  ±8.45% ±11.02%
12:55:40 events/ee-listeners.js raw='false' listeners=50 n=5000000                       -1.08 %       ±1.71%  ±2.28%  ±2.97%
12:55:40 events/ee-listeners.js raw='true' listeners=5 n=5000000                         -3.00 %       ±5.69%  ±7.58%  ±9.89%
12:55:40 events/ee-listeners.js raw='true' listeners=50 n=5000000                         3.68 %       ±4.65%  ±6.18%  ±8.05%
12:55:40 events/ee-once.js argc=0 n=20000000                                             -0.21 %       ±0.64%  ±0.85%  ±1.10%
12:55:40 events/ee-once.js argc=1 n=20000000                                              0.06 %       ±0.44%  ±0.59%  ±0.76%
12:55:40 events/ee-once.js argc=4 n=20000000                                             -0.13 %       ±0.62%  ±0.83%  ±1.08%
12:55:40 events/ee-once.js argc=5 n=20000000                                              0.26 %       ±0.69%  ±0.91%  ±1.19%
12:55:40 events/eventtarget-add-remove.js nListener=10 n=1000000                  **      0.71 %       ±0.42%  ±0.56%  ±0.73%
12:55:40 events/eventtarget-add-remove.js nListener=5 n=1000000                           0.30 %       ±0.70%  ±0.94%  ±1.22%
12:55:40 events/eventtarget-creation.js n=1000000                                         1.95 %       ±3.80%  ±5.09%  ±6.72%
12:55:40 events/eventtarget.js listeners=1 n=1000000                                     -0.66 %       ±5.51%  ±7.34%  ±9.55%
12:55:40 events/eventtarget.js listeners=10 n=1000000                                    -0.32 %       ±3.15%  ±4.19%  ±5.46%
12:55:40 events/eventtarget.js listeners=5 n=1000000                                     -0.39 %       ±5.18%  ±6.90%  ±8.98%
12:55:40 
12:55:40 Be aware that when doing many comparisons the risk of a false-positive
12:55:40 result increases. In this case, there are 37 comparisons, you can thus
12:55:40 expect the following amount of false-positive results:
12:55:40   1.85 false positives, when considering a   5% risk acceptance (*, **, ***),
12:55:40   0.37 false positives, when considering a   1% risk acceptance (**, ***),
12:55:40   0.04 false positives, when considering a 0.1% risk acceptance (***)

nodejs-github-bot added events Issues and PRs related to the events subsystem / EventEmitter. needs-ci PRs that need a full CI run. labels Oct 27, 2023
rluvaton changed the title events: improve creation performance events: improve events performance Oct 27, 2023
rluvaton force-pushed the improve-ee-creation branch from 4c02bdb to bb44f6f Compare October 27, 2023 10:11
rluvaton added the performance Issues and PRs related to the performance of Node.js. label Oct 27, 2023
Comment thread lib/events.js Outdated
Comment thread lib/events.js Outdated
Comment thread lib/events.js Outdated
rluvaton force-pushed the improve-ee-creation branch from bb44f6f to 249c2b8 Compare October 27, 2023 10:51
rluvaton added the request-ci Add this label to start a Jenkins CI on a PR. label Oct 27, 2023
rluvaton requested a review from ronag October 27, 2023 11:06
github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Oct 27, 2023

Copy link
Copy Markdown
Collaborator

rluvaton marked this pull request as draft October 27, 2023 11:22
rluvaton removed the request for review from ronag October 27, 2023 11:22
anonrig added needs-benchmark-ci PR that need a benchmark CI run. needs-citgm PRs that need a CITGM CI run. labels Oct 27, 2023

ronag commented Oct 27, 2023
edited
Loading

Copy link
Copy Markdown
Member

This is probably going to break someone somewhere. That being said, maybe there is a way to minimize it by returning a Proxy from the _events getter that more accurately imitates the original behavior.

Also, I'm surprised this is so much faster. Often the same events are used (e.g. for streams), so I would assume that V8 uses a shape rather than a map behind the scenes, which should be faster than a Map instance. @benjamingr wdyt?

ronag commented Oct 27, 2023

Copy link
Copy Markdown
Member

I'm actually not that interested in ee-listen-unique and ee-once.

rluvaton commented Oct 27, 2023
edited
Loading

Copy link
Copy Markdown
Member Author

Also, I'm surprised this is so much faster. Often the same events are used (e.g. for streams), so I would assume that V8 uses a shape rather than a map behind the scenes, which should be faster than a Map instance.

{ __proto__: null } hint v8 to use the dictionary mode src/runtime/runtime-literals.cc in V8 (founded by @benjamingr)

Copy link
Copy Markdown
Member Author

This is probably going to break someone somewhere. That being said, maybe there is a way to minimize it by returning a Proxy from the _events getter that more accurately imitates the original behavior.

Often the same events are used (e.g. for streams)

you can see the results when removing __proto__ null at the bottom (collapsed)

Copy link
Copy Markdown
Member Author

This is concerning:

16:57:40                                                                                          confidence improvement accuracy (*)   (**)   (***)
16:57:40 streams/creation.js kind='duplex' n=50000000                                                     **      1.61 %       ±0.93% ±1.23%  ±1.61%
16:57:40 streams/creation.js kind='readable' n=50000000                                                  ***    -17.07 %       ±0.68% ±0.91%  ±1.19%
16:57:40 streams/creation.js kind='transform' n=50000000                                                 ***     24.20 %       ±1.46% ±1.95%  ±2.55%
16:57:40 streams/creation.js kind='writable' n=50000000                                                           0.54 %       ±0.92% ±1.23%  ±1.60%
16:57:40 streams/destroy.js kind='duplex' n=1000000                                                       **     -3.85 %       ±2.25% ±2.99%  ±3.90%
16:57:40 streams/destroy.js kind='readable' n=1000000                                                            -0.90 %       ±1.66% ±2.21%  ±2.88%
16:57:40 streams/destroy.js kind='transform' n=1000000                                                           -1.38 %       ±1.91% ±2.54%  ±3.31%
16:57:40 streams/destroy.js kind='writable' n=1000000                                                            -2.12 %       ±2.19% ±2.91%  ±3.80%
16:57:40 streams/pipe-object-mode.js n=5000000                                                             *      6.22 %       ±5.34% ±7.11%  ±9.26%
16:57:40 streams/pipe.js n=5000000                                                                       ***      7.73 %       ±3.87% ±5.15%  ±6.70%
16:57:40 streams/readable-async-iterator.js sync='no' n=100000                                                   -2.28 %       ±6.37% ±8.48% ±11.05%
16:57:40 streams/readable-async-iterator.js sync='yes' n=100000                                                  -0.80 %       ±5.49% ±7.30%  ±9.51%
16:57:40 streams/readable-bigread.js n=1000                                                                *      3.49 %       ±2.92% ±3.92%  ±5.17%
16:57:40 streams/readable-bigunevenread.js n=1000                                                                -0.62 %       ±3.22% ±4.33%  ±5.72%
16:57:40 streams/readable-boundaryread.js type='buffer' n=2000                                           ***     11.62 %       ±1.13% ±1.50%  ±1.95%
16:57:40 streams/readable-boundaryread.js type='string' n=2000                                                    2.67 %       ±3.46% ±4.61%  ±6.03%
16:57:40 streams/readable-from.js type='array' n=10000000                                                         4.68 %       ±5.29% ±7.05%  ±9.18%
16:57:40 streams/readable-from.js type='async-generator' n=10000000                                      ***      2.44 %       ±0.90% ±1.20%  ±1.56%
16:57:40 streams/readable-from.js type='sync-generator-with-async-values' n=10000000                     ***      4.27 %       ±0.99% ±1.32%  ±1.71%
16:57:40 streams/readable-from.js type='sync-generator-with-sync-values' n=10000000                               2.93 %       ±4.20% ±5.59%  ±7.28%
16:57:40 streams/readable-readall.js n=5000                                                                      -1.18 %       ±6.06% ±8.06% ±10.50%
16:57:40 streams/readable-unevenread.js n=1000                                                           ***      3.97 %       ±2.02% ±2.68%  ±3.49%
16:57:40 streams/writable-manywrites.js len=1024 callback='no' writev='no' sync='no' n=100000            ***     -3.08 %       ±1.04% ±1.38%  ±1.79%
16:57:40 streams/writable-manywrites.js len=1024 callback='no' writev='no' sync='yes' n=100000                    0.94 %       ±1.97% ±2.63%  ±3.43%
16:57:40 streams/writable-manywrites.js len=1024 callback='no' writev='yes' sync='no' n=100000           ***     -6.76 %       ±2.49% ±3.34%  ±4.39%
16:57:40 streams/writable-manywrites.js len=1024 callback='no' writev='yes' sync='yes' n=100000                  -3.66 %       ±4.38% ±5.84%  ±7.63%
16:57:40 streams/writable-manywrites.js len=1024 callback='yes' writev='no' sync='no' n=100000                   -2.13 %       ±3.01% ±4.01%  ±5.22%
16:57:40 streams/writable-manywrites.js len=1024 callback='yes' writev='no' sync='yes' n=100000                  -1.16 %       ±2.15% ±2.86%  ±3.72%
16:57:40 streams/writable-manywrites.js len=1024 callback='yes' writev='yes' sync='no' n=100000          ***     -4.85 %       ±2.67% ±3.56%  ±4.66%
16:57:40 streams/writable-manywrites.js len=1024 callback='yes' writev='yes' sync='yes' n=100000                 -1.77 %       ±3.70% ±4.95%  ±6.49%
16:57:40 streams/writable-manywrites.js len=32768 callback='no' writev='no' sync='no' n=100000                    0.89 %       ±3.28% ±4.39%  ±5.76%
16:57:40 streams/writable-manywrites.js len=32768 callback='no' writev='no' sync='yes' n=100000                  -1.94 %       ±3.64% ±4.85%  ±6.31%
16:57:40 streams/writable-manywrites.js len=32768 callback='no' writev='yes' sync='no' n=100000            *     -1.35 %       ±1.11% ±1.47%  ±1.92%
16:57:40 streams/writable-manywrites.js len=32768 callback='no' writev='yes' sync='yes' n=100000                 -2.63 %       ±3.85% ±5.12%  ±6.67%
16:57:40 streams/writable-manywrites.js len=32768 callback='yes' writev='no' sync='no' n=100000                   1.63 %       ±3.13% ±4.19%  ±5.53%
16:57:40 streams/writable-manywrites.js len=32768 callback='yes' writev='no' sync='yes' n=100000                 -1.37 %       ±2.82% ±3.75%  ±4.89%
16:57:40 streams/writable-manywrites.js len=32768 callback='yes' writev='yes' sync='no' n=100000          **     -1.50 %       ±1.09% ±1.44%  ±1.88%
16:57:40 streams/writable-manywrites.js len=32768 callback='yes' writev='yes' sync='yes' n=100000                -1.05 %       ±2.24% ±2.98%  ±3.88%
16:57:40 
16:57:40 Be aware that when doing many comparisons the risk of a false-positive
16:57:40 result increases. In this case, there are 38 comparisons, you can thus
16:57:40 expect the following amount of false-positive results:
16:57:40   1.90 false positives, when considering a   5% risk acceptance (*, **, ***),
16:57:40   0.38 false positives, when considering a   1% risk acceptance (**, ***),
16:57:40   0.04 false positives, when considering a 0.1% risk acceptance (***)

benjamingr 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

This is neat but I don't understand how it's faster since objects in dictionary mode and maps have basically the same performance.

Also the "polyfill" for ._eventsis incorrect since if someone sets a value on it it won't get reflected in the emitter.

ronag commented Oct 27, 2023

Copy link
Copy Markdown
Member

{ proto: null } hint v8 to use the dictionary mod

What happens if you remove that hint? Sorry it's a bit unclear what your last benchmark results are from.

rluvaton commented Oct 27, 2023
edited
Loading

Copy link
Copy Markdown
Member Author

Also the "polyfill" for ._eventsis incorrect since if someone sets a value on it it won't get reflected in the emitter.

I know I still have a todo there to convert to Proxy so it support everything

This is neat but I don't understand how it's faster since objects in dictionary mode and maps have basically the same performance.

Maybe because it by default go to the dict mode?

{ proto: null } hint v8 to use the dictionary mod

What happens if you remove that hint? Sorry it's a bit unclear what your last benchmark results are from.

the benchmarks are from the linked commit

change _events to be without __proto__: null

Commit: eb29e97

I think the performance without proto is not fully representative as the event name can be anything so the dictionary mode is not used here

Benchmark URL

12:55:39 ++ Rscript benchmark/compare.R
12:55:40                                                                  confidence improvement accuracy (*)    (**)   (***)
12:55:40 events/ee-add-remove.js n=1000000 removeListener=0 newListener=0         **     -2.22 %       ±1.50%  ±2.00%  ±2.60%
12:55:40 events/ee-add-remove.js n=1000000 removeListener=0 newListener=1        ***     30.34 %       ±1.75%  ±2.33%  ±3.04%
12:55:40 events/ee-add-remove.js n=1000000 removeListener=1 newListener=0        ***     22.74 %       ±1.17%  ±1.56%  ±2.03%
12:55:40 events/ee-add-remove.js n=1000000 removeListener=1 newListener=1        ***     10.04 %       ±1.11%  ±1.47%  ±1.92%
12:55:40 events/ee-emit.js listeners=1 argc=0 n=2000000                          ***    159.54 %       ±8.72% ±11.64% ±15.20%
12:55:40 events/ee-emit.js listeners=1 argc=10 n=2000000                         ***    139.14 %      ±12.44% ±16.59% ±21.66%
12:55:40 events/ee-emit.js listeners=1 argc=2 n=2000000                          ***    159.56 %      ±13.83% ±18.46% ±24.15%
12:55:40 events/ee-emit.js listeners=1 argc=4 n=2000000                          ***    148.52 %      ±10.04% ±13.37% ±17.43%
12:55:40 events/ee-emit.js listeners=10 argc=0 n=2000000                         ***     13.34 %       ±7.48%  ±9.96% ±12.96%
12:55:40 events/ee-emit.js listeners=10 argc=10 n=2000000                        ***     11.22 %       ±5.66%  ±7.53%  ±9.81%
12:55:40 events/ee-emit.js listeners=10 argc=2 n=2000000                                  3.11 %       ±6.21%  ±8.27% ±10.77%
12:55:40 events/ee-emit.js listeners=10 argc=4 n=2000000                         ***     12.07 %       ±6.04%  ±8.04% ±10.47%
12:55:40 events/ee-emit.js listeners=5 argc=0 n=2000000                          ***     20.76 %       ±9.34% ±12.44% ±16.24%
12:55:40 events/ee-emit.js listeners=5 argc=10 n=2000000                         ***     17.29 %       ±8.71% ±11.59% ±15.10%
12:55:40 events/ee-emit.js listeners=5 argc=2 n=2000000                            *     13.10 %       ±9.93% ±13.21% ±17.20%
12:55:40 events/ee-emit.js listeners=5 argc=4 n=2000000                            *      9.82 %       ±9.51% ±12.66% ±16.48%
12:55:40 events/ee-listen-unique.js n=1000000 events=1                                    0.24 %       ±1.32%  ±1.76%  ±2.29%
12:55:40 events/ee-listen-unique.js n=1000000 events=10                          ***     -3.02 %       ±1.08%  ±1.44%  ±1.88%
12:55:40 events/ee-listen-unique.js n=1000000 events=2                           ***     -2.28 %       ±0.69%  ±0.92%  ±1.20%
12:55:40 events/ee-listen-unique.js n=1000000 events=20                           **     -2.16 %       ±1.56%  ±2.09%  ±2.73%
12:55:40 events/ee-listen-unique.js n=1000000 events=3                           ***     -2.03 %       ±0.98%  ±1.31%  ±1.71%
12:55:40 events/ee-listen-unique.js n=1000000 events=5                           ***     -4.36 %       ±0.89%  ±1.19%  ±1.55%
12:55:40 events/ee-listener-count-on-prototype.js n=50000000                     ***     -6.40 %       ±3.40%  ±4.53%  ±5.91%
12:55:40 events/ee-listeners.js raw='false' listeners=5 n=5000000                  *     -8.30 %       ±6.34%  ±8.45% ±11.02%
12:55:40 events/ee-listeners.js raw='false' listeners=50 n=5000000                       -1.08 %       ±1.71%  ±2.28%  ±2.97%
12:55:40 events/ee-listeners.js raw='true' listeners=5 n=5000000                         -3.00 %       ±5.69%  ±7.58%  ±9.89%
12:55:40 events/ee-listeners.js raw='true' listeners=50 n=5000000                         3.68 %       ±4.65%  ±6.18%  ±8.05%
12:55:40 events/ee-once.js argc=0 n=20000000                                             -0.21 %       ±0.64%  ±0.85%  ±1.10%
12:55:40 events/ee-once.js argc=1 n=20000000                                              0.06 %       ±0.44%  ±0.59%  ±0.76%
12:55:40 events/ee-once.js argc=4 n=20000000                                             -0.13 %       ±0.62%  ±0.83%  ±1.08%
12:55:40 events/ee-once.js argc=5 n=20000000                                              0.26 %       ±0.69%  ±0.91%  ±1.19%
12:55:40 events/eventtarget-add-remove.js nListener=10 n=1000000                  **      0.71 %       ±0.42%  ±0.56%  ±0.73%
12:55:40 events/eventtarget-add-remove.js nListener=5 n=1000000                           0.30 %       ±0.70%  ±0.94%  ±1.22%
12:55:40 events/eventtarget-creation.js n=1000000                                         1.95 %       ±3.80%  ±5.09%  ±6.72%
12:55:40 events/eventtarget.js listeners=1 n=1000000                                     -0.66 %       ±5.51%  ±7.34%  ±9.55%
12:55:40 events/eventtarget.js listeners=10 n=1000000                                    -0.32 %       ±3.15%  ±4.19%  ±5.46%
12:55:40 events/eventtarget.js listeners=5 n=1000000                                     -0.39 %       ±5.18%  ±6.90%  ±8.98%
12:55:40 
12:55:40 Be aware that when doing many comparisons the risk of a false-positive
12:55:40 result increases. In this case, there are 37 comparisons, you can thus
12:55:40 expect the following amount of false-positive results:
12:55:40   1.85 false positives, when considering a   5% risk acceptance (*, **, ***),
12:55:40   0.37 false positives, when considering a   1% risk acceptance (**, ***),
12:55:40   0.04 false positives, when considering a 0.1% risk acceptance (***)

ronag commented Oct 27, 2023

Copy link
Copy Markdown
Member

change _events to be without proto: null

Looks great to me!

ronag commented Oct 27, 2023

Copy link
Copy Markdown
Member

Also what about something like the following for streams?

diff --git a/lib/internal/streams/duplex.js b/lib/internal/streams/duplex.js
index 834d875be6..2b3fe64df9 100644
--- a/lib/internal/streams/duplex.js
+++ b/lib/internal/streams/duplex.js
@@ -63,6 +63,21 @@ function Duplex(options) {
   if (!(this instanceof Duplex))
     return new Duplex(options);
 
+  this._events = {
+    close: undefined,
+    error: undefined,
+    prefinish: undefined,
+    finish: undefined,
+    drain: undefined,
+    data: undefined,
+    end: undefined,
+    pause: undefined,
+    resume: undefined,
+    readable: undefined,
+    pipe: undefined,
+    unpipe: undefined,
+  };
+
   this._readableState = new Readable.ReadableState(options, this, true);
   this._writableState = new Writable.WritableState(options, this, true);
 
diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js
index 80798a35dc..83f09194a6 100644
--- a/lib/internal/streams/readable.js
+++ b/lib/internal/streams/readable.js
@@ -316,6 +316,18 @@ function Readable(options) {
   if (!(this instanceof Readable))
     return new Readable(options);
 
+  this._events = {
+    close: undefined,
+    error: undefined,
+    data: undefined,
+    end: undefined,
+    pause: undefined,
+    resume: undefined,
+    readable: undefined,
+    pipe: undefined,
+    unpipe: undefined,
+  };
+
   this._readableState = new ReadableState(options, this, false);
 
   if (options) {
diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js
index 74573033ea..69fb2be7f0 100644
--- a/lib/internal/streams/writable.js
+++ b/lib/internal/streams/writable.js
@@ -382,6 +382,14 @@ function Writable(options) {
   if (!(this instanceof Writable))
     return new Writable(options);
 
+    this._events = {
+      close: undefined,
+      error: undefined,
+      prefinish: undefined,
+      finish: undefined,
+      drain: undefined,
+    };
+
   this._writableState = new WritableState(options, this, false);
 
   if (options) {

Copy link
Copy Markdown
Member Author

Do you think it's representative, I think the reason someone put __proto__ null was to be in dict mode

Copy link
Copy Markdown
Member Author

Also what about something like the following for streams?

diff --git a/lib/internal/streams/duplex.js b/lib/internal/streams/duplex.js
index 834d875be6..2b3fe64df9 100644
--- a/lib/internal/streams/duplex.js
+++ b/lib/internal/streams/duplex.js
@@ -63,6 +63,21 @@ function Duplex(options) {
   if (!(this instanceof Duplex))
     return new Duplex(options);
 
+  this._events = {
+    close: undefined,
+    error: undefined,
+    prefinish: undefined,
+    finish: undefined,
+    drain: undefined,
+    data: undefined,
+    end: undefined,
+    pause: undefined,
+    resume: undefined,
+    readable: undefined,
+    pipe: undefined,
+    unpipe: undefined,
+  };
+
   this._readableState = new Readable.ReadableState(options, this, true);
   this._writableState = new Writable.WritableState(options, this, true);
 
diff --git a/lib/internal/streams/readable.js b/lib/internal/streams/readable.js
index 80798a35dc..83f09194a6 100644
--- a/lib/internal/streams/readable.js
+++ b/lib/internal/streams/readable.js
@@ -316,6 +316,18 @@ function Readable(options) {
   if (!(this instanceof Readable))
     return new Readable(options);
 
+  this._events = {
+    close: undefined,
+    error: undefined,
+    data: undefined,
+    end: undefined,
+    pause: undefined,
+    resume: undefined,
+    readable: undefined,
+    pipe: undefined,
+    unpipe: undefined,
+  };
+
   this._readableState = new ReadableState(options, this, false);
 
   if (options) {
diff --git a/lib/internal/streams/writable.js b/lib/internal/streams/writable.js
index 74573033ea..69fb2be7f0 100644
--- a/lib/internal/streams/writable.js
+++ b/lib/internal/streams/writable.js
@@ -382,6 +382,14 @@ function Writable(options) {
   if (!(this instanceof Writable))
     return new Writable(options);
 
+    this._events = {
+      close: undefined,
+      error: undefined,
+      prefinish: undefined,
+      finish: undefined,
+      drain: undefined,
+    };
+
   this._writableState = new WritableState(options, this, false);
 
   if (options) {

I thought about that, but since I changed to Map I did not do it

Copy link
Copy Markdown
Member

Eh, this makes one use case slower and another one faster (changing to no proto: null), making "EventEmitter events shape specific to common use cases for streams" could be worth it, with benchmarks

lpinca commented Oct 27, 2023

Copy link
Copy Markdown
Member

Possible duplicate of #44627 and #39939. See also #11930.

Copy link
Copy Markdown
Member Author

Supersede by #50428

rluvaton closed this Oct 29, 2023
rluvaton deleted the improve-ee-creation branch October 29, 2023 10:21
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

events Issues and PRs related to the events subsystem / EventEmitter. needs-benchmark-ci PR that need a benchmark CI run. needs-ci PRs that need a full CI run. needs-citgm PRs that need a CITGM CI run. performance Issues and PRs related to the performance of Node.js.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants


Back | FazBrowse Home | New Git URL