| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Sorry, something went wrong.
|
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? |
Sorry, something went wrong.
|
I'm actually not that interested in ee-listen-unique and ee-once. |
Sorry, something went wrong.
{ __proto__: null } hint v8 to use the dictionary mode src/runtime/runtime-literals.cc in V8 (founded by @benjamingr) |
Sorry, something went wrong.
you can see the results when removing __proto__ null at the bottom (collapsed) |
Sorry, something went wrong.
|
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 (***) |
Sorry, something went wrong.
There was a problem hiding this comment.
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.
Sorry, something went wrong.
What happens if you remove that hint? Sorry it's a bit unclear what your last benchmark results are from. |
Sorry, something went wrong.
I know I still have a todo there to convert to Proxy so it support everything
Maybe because it by default go to the dict mode?
the benchmarks are from the linked commit change _events to be without __proto__: nullCommit: 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 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 (***) |
Sorry, something went wrong.
Looks great to me! |
Sorry, something went wrong.
|
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) {
|
Sorry, something went wrong.
|
Do you think it's representative, I think the reason someone put __proto__ null was to be in dict mode |
Sorry, something went wrong.
I thought about that, but since I changed to Map I did not do it |
Sorry, something went wrong.
|
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 |
Sorry, something went wrong.
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Benchmarks
Change _events to be a Map:
commit: 249c2b8
Notes:
Benchmark URL
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__: nullchange _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