events: add fast and slow path
Thank you @benjamingr for the idea
WIP!!!, fixed most of the tests
TODO
-
fix a lot of TODOs -
Extract to files -
fix the commits here and avoid the merge commit -
Extract files separation to different PR after all test pass and we are happy-ish that we are willing to to merge it https://github.com/nodejs/node/pull/52726 maybe split to multiple commits to keep the history of original events file -
fix failing tests -
Check lib/domain.js
as it override emit function -
Check streams performance as well to see how it is affected -
Optimize for streams which has kCapture
enabled -
Fix performance penalty in streams -
Run CITGM so we can be sure we are not breaking anyone as this is sensitive place
Benchmarks
events
confidence improvement accuracy (*) (**) (***)
events/ee-add-remove.js n=1000000 removeListener=0 newListener=0 -0.25 % ±0.71% ±0.95% ±1.24%
events/ee-add-remove.js n=1000000 removeListener=0 newListener=1 *** 10.22 % ±0.63% ±0.84% ±1.10%
events/ee-add-remove.js n=1000000 removeListener=1 newListener=0 0.23 % ±0.71% ±0.95% ±1.24%
events/ee-add-remove.js n=1000000 removeListener=1 newListener=1 *** 7.33 % ±0.85% ±1.13% ±1.48%
events/ee-emit.js listeners=1 argc=0 n=2000000 *** 111.60 % ±6.32% ±8.47% ±11.14%
events/ee-emit.js listeners=1 argc=10 n=2000000 *** -21.98 % ±1.40% ±1.86% ±2.42%
events/ee-emit.js listeners=1 argc=2 n=2000000 *** 110.07 % ±4.38% ±5.83% ±7.59%
events/ee-emit.js listeners=1 argc=4 n=2000000 *** 99.87 % ±5.63% ±7.49% ±9.75%
events/ee-emit.js listeners=10 argc=0 n=2000000 *** 7.45 % ±0.80% ±1.08% ±1.42%
events/ee-emit.js listeners=10 argc=10 n=2000000 *** 6.16 % ±0.44% ±0.59% ±0.77%
events/ee-emit.js listeners=10 argc=2 n=2000000 *** 7.60 % ±0.79% ±1.05% ±1.36%
events/ee-emit.js listeners=10 argc=4 n=2000000 *** 7.78 % ±1.17% ±1.57% ±2.07%
events/ee-emit.js listeners=5 argc=0 n=2000000 *** 17.87 % ±1.36% ±1.81% ±2.36%
events/ee-emit.js listeners=5 argc=10 n=2000000 *** 13.65 % ±1.13% ±1.50% ±1.96%
events/ee-emit.js listeners=5 argc=2 n=2000000 *** 7.37 % ±1.26% ±1.69% ±2.22%
events/ee-emit.js listeners=5 argc=4 n=2000000 *** 18.39 % ±1.30% ±1.74% ±2.27%
events/ee-listen-unique.js n=1000000 events=1 0.13 % ±0.47% ±0.63% ±0.82%
events/ee-listen-unique.js n=1000000 events=10 * 1.20 % ±1.12% ±1.49% ±1.94%
events/ee-listen-unique.js n=1000000 events=2 * -0.75 % ±0.71% ±0.94% ±1.23%
events/ee-listen-unique.js n=1000000 events=20 0.35 % ±1.39% ±1.85% ±2.41%
events/ee-listen-unique.js n=1000000 events=3 ** -1.68 % ±1.11% ±1.48% ±1.94%
events/ee-listen-unique.js n=1000000 events=5 0.10 % ±0.96% ±1.28% ±1.67%
events/ee-listener-count-on-prototype.js n=50000000 *** -16.68 % ±1.27% ±1.70% ±2.24%
events/ee-listeners.js raw='false' listeners=5 n=5000000 *** -6.19 % ±0.83% ±1.11% ±1.44%
events/ee-listeners.js raw='false' listeners=50 n=5000000 *** -2.50 % ±0.48% ±0.64% ±0.83%
events/ee-listeners.js raw='true' listeners=5 n=5000000 *** -9.56 % ±0.95% ±1.27% ±1.65%
events/ee-listeners.js raw='true' listeners=50 n=5000000 *** -1.63 % ±0.64% ±0.86% ±1.12%
events/ee-once.js argc=0 n=20000000 *** 17.17 % ±1.12% ±1.49% ±1.96%
events/ee-once.js argc=1 n=20000000 *** 14.88 % ±1.57% ±2.11% ±2.78%
events/ee-once.js argc=4 n=20000000 *** 11.77 % ±0.71% ±0.95% ±1.24%
events/ee-once.js argc=5 n=20000000 *** 12.95 % ±1.20% ±1.60% ±2.08%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 31 comparisons, you can thus
expect the following amount of false-positive results:
1.55 false positives, when considering a 5% risk acceptance (*, **, ***),
0.31 false positives, when considering a 1% risk acceptance (**, ***),
0.03 false positives, when considering a 0.1% risk acceptance (***)
outdated benchmark result
confidence improvement accuracy (*) (**) (***)
events/ee-add-remove.js n=1000000 removeListener=0 newListener=0 *** 1.08 % ±0.57% ±0.76% ±0.99%
events/ee-add-remove.js n=1000000 removeListener=0 newListener=1 *** 11.93 % ±0.69% ±0.92% ±1.20%
events/ee-add-remove.js n=1000000 removeListener=1 newListener=0 ** 1.10 % ±0.75% ±0.99% ±1.29%
events/ee-add-remove.js n=1000000 removeListener=1 newListener=1 *** 7.78 % ±0.71% ±0.95% ±1.24%
events/ee-emit.js listeners=1 argc=0 n=2000000 *** 110.02 % ±2.90% ±3.86% ±5.03%
events/ee-emit.js listeners=1 argc=10 n=2000000 *** -21.73 % ±3.21% ±4.28% ±5.57%
events/ee-emit.js listeners=1 argc=2 n=2000000 *** 102.72 % ±5.43% ±7.24% ±9.48%
events/ee-emit.js listeners=1 argc=4 n=2000000 *** 98.91 % ±6.48% ±8.66% ±11.35%
events/ee-emit.js listeners=10 argc=0 n=2000000 *** 8.77 % ±0.73% ±0.97% ±1.26%
events/ee-emit.js listeners=10 argc=10 n=2000000 *** 6.19 % ±0.39% ±0.52% ±0.68%
events/ee-emit.js listeners=10 argc=2 n=2000000 *** 6.92 % ±0.88% ±1.17% ±1.54%
events/ee-emit.js listeners=10 argc=4 n=2000000 *** 6.71 % ±0.76% ±1.01% ±1.32%
events/ee-emit.js listeners=5 argc=0 n=2000000 *** 17.82 % ±0.90% ±1.20% ±1.56%
events/ee-emit.js listeners=5 argc=10 n=2000000 *** 14.79 % ±0.75% ±0.99% ±1.29%
events/ee-emit.js listeners=5 argc=2 n=2000000 *** 7.11 % ±0.94% ±1.25% ±1.63%
events/ee-emit.js listeners=5 argc=4 n=2000000 *** 17.21 % ±1.11% ±1.48% ±1.94%
events/ee-listen-unique.js n=1000000 events=1 0.27 % ±0.53% ±0.70% ±0.91%
events/ee-listen-unique.js n=1000000 events=10 ** 1.72 % ±1.06% ±1.41% ±1.83%
events/ee-listen-unique.js n=1000000 events=2 0.05 % ±0.82% ±1.09% ±1.41%
events/ee-listen-unique.js n=1000000 events=20 0.96 % ±1.36% ±1.81% ±2.36%
events/ee-listen-unique.js n=1000000 events=3 ** 1.51 % ±1.10% ±1.46% ±1.90%
events/ee-listen-unique.js n=1000000 events=5 ** 1.65 % ±0.98% ±1.31% ±1.70%
events/ee-listener-count-on-prototype.js n=50000000 *** -16.19 % ±1.44% ±1.93% ±2.54%
events/ee-listeners.js raw='false' listeners=5 n=5000000 *** -5.07 % ±0.57% ±0.76% ±0.99%
events/ee-listeners.js raw='false' listeners=50 n=5000000 *** -1.68 % ±0.46% ±0.61% ±0.79%
events/ee-listeners.js raw='true' listeners=5 n=5000000 *** -10.91 % ±1.03% ±1.37% ±1.78%
events/ee-listeners.js raw='true' listeners=50 n=5000000 ** 0.93 % ±0.61% ±0.81% ±1.06%
events/ee-once.js argc=0 n=20000000 *** 15.84 % ±1.81% ±2.41% ±3.14%
events/ee-once.js argc=1 n=20000000 *** 13.77 % ±1.16% ±1.56% ±2.07%
events/ee-once.js argc=4 n=20000000 *** 11.74 % ±0.63% ±0.84% ±1.09%
events/ee-once.js argc=5 n=20000000 *** 13.90 % ±1.14% ±1.53% ±2.01%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 31 comparisons, you can thus
expect the following amount of false-positive results:
1.55 false positives, when considering a 5% risk acceptance (*, **, ***),
0.31 false positives, when considering a 1% risk acceptance (**, ***),
0.03 false positives, when considering a 0.1% risk acceptance (***)
streams
confidence improvement accuracy (*) (**) (***)
streams/creation.js kind='duplex' n=50000000 *** -9.96 % ±0.80% ±1.07% ±1.41%
streams/creation.js kind='readable' n=50000000 *** -44.18 % ±0.76% ±1.01% ±1.32%
streams/creation.js kind='transform' n=50000000 *** -18.93 % ±2.04% ±2.72% ±3.56%
streams/creation.js kind='writable' n=50000000 *** -18.20 % ±0.74% ±0.99% ±1.29%
streams/destroy.js kind='duplex' n=1000000 *** -12.26 % ±0.48% ±0.64% ±0.83%
streams/destroy.js kind='readable' n=1000000 *** -24.42 % ±1.65% ±2.22% ±2.93%
streams/destroy.js kind='transform' n=1000000 *** -12.58 % ±0.42% ±0.56% ±0.72%
streams/destroy.js kind='writable' n=1000000 *** -18.84 % ±0.76% ±1.01% ±1.32%
streams/pipe-object-mode.js n=5000000 *** 5.45 % ±0.33% ±0.44% ±0.57%
streams/pipe.js n=5000000 ** 0.88 % ±0.60% ±0.81% ±1.07%
streams/readable-async-iterator.js sync='no' n=100000 *** -1.97 % ±0.94% ±1.26% ±1.64%
streams/readable-async-iterator.js sync='yes' n=100000 ** -1.14 % ±0.76% ±1.01% ±1.32%
streams/readable-bigread.js n=1000 ** -1.04 % ±0.65% ±0.86% ±1.12%
streams/readable-bigunevenread.js n=1000 -0.04 % ±0.39% ±0.52% ±0.68%
streams/readable-boundaryread.js type='buffer' n=2000 *** -2.21 % ±0.76% ±1.01% ±1.32%
streams/readable-boundaryread.js type='string' n=2000 *** -4.15 % ±1.12% ±1.50% ±1.95%
streams/readable-from.js type='array' n=10000000 *** -6.15 % ±1.71% ±2.27% ±2.96%
streams/readable-from.js type='async-generator' n=10000000 *** -2.72 % ±1.39% ±1.87% ±2.47%
streams/readable-from.js type='sync-generator-with-async-values' n=10000000 ** -2.66 % ±1.56% ±2.10% ±2.78%
streams/readable-from.js type='sync-generator-with-sync-values' n=10000000 *** -2.72 % ±0.20% ±0.27% ±0.35%
streams/readable-readall.js n=5000 * 1.68 % ±1.61% ±2.14% ±2.79%
streams/readable-uint8array.js kind='encoding' n=1000000 *** -2.76 % ±0.61% ±0.82% ±1.07%
streams/readable-uint8array.js kind='read' n=1000000 -0.57 % ±1.33% ±1.77% ±2.31%
streams/readable-unevenread.js n=1000 -0.84 % ±0.92% ±1.22% ±1.60%
streams/writable-manywrites.js len=1024 callback='no' writev='no' sync='no' n=100000 -1.84 % ±2.03% ±2.70% ±3.52%
streams/writable-manywrites.js len=1024 callback='no' writev='no' sync='yes' n=100000 -0.42 % ±1.14% ±1.53% ±1.99%
streams/writable-manywrites.js len=1024 callback='no' writev='yes' sync='no' n=100000 *** -1.81 % ±0.69% ±0.92% ±1.20%
streams/writable-manywrites.js len=1024 callback='no' writev='yes' sync='yes' n=100000 -0.47 % ±1.20% ±1.60% ±2.08%
streams/writable-manywrites.js len=1024 callback='yes' writev='no' sync='no' n=100000 -0.07 % ±1.83% ±2.44% ±3.19%
streams/writable-manywrites.js len=1024 callback='yes' writev='no' sync='yes' n=100000 * -0.76 % ±0.64% ±0.85% ±1.11%
streams/writable-manywrites.js len=1024 callback='yes' writev='yes' sync='no' n=100000 * -1.62 % ±1.35% ±1.80% ±2.35%
streams/writable-manywrites.js len=1024 callback='yes' writev='yes' sync='yes' n=100000 0.15 % ±1.65% ±2.20% ±2.86%
streams/writable-manywrites.js len=32768 callback='no' writev='no' sync='no' n=100000 2.42 % ±2.78% ±3.70% ±4.83%
streams/writable-manywrites.js len=32768 callback='no' writev='no' sync='yes' n=100000 * -0.81 % ±0.64% ±0.86% ±1.12%
streams/writable-manywrites.js len=32768 callback='no' writev='yes' sync='no' n=100000 -0.09 % ±2.87% ±3.84% ±5.02%
streams/writable-manywrites.js len=32768 callback='no' writev='yes' sync='yes' n=100000 -0.02 % ±1.66% ±2.23% ±2.94%
streams/writable-manywrites.js len=32768 callback='yes' writev='no' sync='no' n=100000 -1.29 % ±2.19% ±2.92% ±3.81%
streams/writable-manywrites.js len=32768 callback='yes' writev='no' sync='yes' n=100000 * -1.48 % ±1.24% ±1.65% ±2.15%
streams/writable-manywrites.js len=32768 callback='yes' writev='yes' sync='no' n=100000 *** -2.44 % ±1.04% ±1.38% ±1.80%
streams/writable-manywrites.js len=32768 callback='yes' writev='yes' sync='yes' n=100000 -0.25 % ±0.84% ±1.12% ±1.46%
streams/writable-uint8array.js kind='object-mode' n=50000000 * 0.93 % ±0.87% ±1.16% ±1.51%
streams/writable-uint8array.js kind='write' n=50000000 * -0.22 % ±0.20% ±0.26% ±0.34%
streams/writable-uint8array.js kind='writev' n=50000000 * -0.30 % ±0.26% ±0.34% ±0.44%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 43 comparisons, you can thus
expect the following amount of false-positive results:
2.15 false positives, when considering a 5% risk acceptance (*, **, ***),
0.43 false positives, when considering a 1% risk acceptance (**, ***),
0.04 false positives, when considering a 0.1% risk acceptance (***)
outdated benchmark result
confidence improvement accuracy (*) (**) (***)
streams/creation.js kind='duplex' n=50000000 *** -9.03 % ±0.87% ±1.15% ±1.50%
streams/creation.js kind='readable' n=50000000 *** -39.48 % ±0.54% ±0.72% ±0.94%
streams/creation.js kind='transform' n=50000000 *** -15.64 % ±2.26% ±3.00% ±3.91%
streams/creation.js kind='writable' n=50000000 *** -19.24 % ±0.59% ±0.78% ±1.02%
streams/destroy.js kind='duplex' n=1000000 ** -0.81 % ±0.55% ±0.74% ±0.96%
streams/destroy.js kind='readable' n=1000000 *** -26.99 % ±0.83% ±1.10% ±1.44%
streams/destroy.js kind='transform' n=1000000 *** -16.89 % ±0.42% ±0.56% ±0.73%
streams/destroy.js kind='writable' n=1000000 *** -20.11 % ±0.79% ±1.06% ±1.38%
streams/pipe-object-mode.js n=5000000 *** 5.06 % ±0.29% ±0.39% ±0.50%
streams/pipe.js n=5000000 *** 1.32 % ±0.57% ±0.76% ±1.00%
streams/readable-async-iterator.js sync='no' n=100000 ** -1.31 % ±0.85% ±1.14% ±1.48%
streams/readable-async-iterator.js sync='yes' n=100000 *** -3.91 % ±1.93% ±2.58% ±3.39%
streams/readable-bigread.js n=1000 *** -1.71 % ±0.77% ±1.03% ±1.35%
streams/readable-bigunevenread.js n=1000 *** -1.16 % ±0.63% ±0.84% ±1.10%
streams/readable-boundaryread.js type='buffer' n=2000 *** -2.48 % ±0.77% ±1.02% ±1.33%
streams/readable-boundaryread.js type='string' n=2000 *** 1.78 % ±0.87% ±1.16% ±1.51%
streams/readable-from.js type='array' n=10000000 ** -5.00 % ±3.71% ±4.94% ±6.43%
streams/readable-from.js type='async-generator' n=10000000 ** -2.54 % ±1.44% ±1.93% ±2.54%
streams/readable-from.js type='sync-generator-with-async-values' n=10000000 *** -2.80 % ±1.46% ±1.97% ±2.61%
streams/readable-from.js type='sync-generator-with-sync-values' n=10000000 *** -2.84 % ±0.17% ±0.23% ±0.30%
streams/readable-readall.js n=5000 1.38 % ±1.75% ±2.32% ±3.02%
streams/readable-uint8array.js kind='encoding' n=1000000 0.21 % ±1.12% ±1.49% ±1.94%
streams/readable-uint8array.js kind='read' n=1000000 *** 6.38 % ±1.03% ±1.38% ±1.81%
streams/readable-unevenread.js n=1000 0.18 % ±0.92% ±1.22% ±1.59%
streams/writable-manywrites.js len=1024 callback='no' writev='no' sync='no' n=100000 -0.92 % ±1.96% ±2.62% ±3.41%
streams/writable-manywrites.js len=1024 callback='no' writev='no' sync='yes' n=100000 * -0.90 % ±0.81% ±1.07% ±1.40%
streams/writable-manywrites.js len=1024 callback='no' writev='yes' sync='no' n=100000 ** -2.29 % ±1.65% ±2.19% ±2.85%
streams/writable-manywrites.js len=1024 callback='no' writev='yes' sync='yes' n=100000 * -0.81 % ±0.67% ±0.89% ±1.17%
streams/writable-manywrites.js len=1024 callback='yes' writev='no' sync='no' n=100000 -1.59 % ±1.78% ±2.37% ±3.10%
streams/writable-manywrites.js len=1024 callback='yes' writev='no' sync='yes' n=100000 * -0.65 % ±0.50% ±0.66% ±0.86%
streams/writable-manywrites.js len=1024 callback='yes' writev='yes' sync='no' n=100000 *** -4.28 % ±1.77% ±2.36% ±3.09%
streams/writable-manywrites.js len=1024 callback='yes' writev='yes' sync='yes' n=100000 -0.35 % ±1.28% ±1.70% ±2.21%
streams/writable-manywrites.js len=32768 callback='no' writev='no' sync='no' n=100000 0.55 % ±2.74% ±3.65% ±4.75%
streams/writable-manywrites.js len=32768 callback='no' writev='no' sync='yes' n=100000 *** -1.16 % ±0.60% ±0.81% ±1.05%
streams/writable-manywrites.js len=32768 callback='no' writev='yes' sync='no' n=100000 -1.54 % ±1.85% ±2.46% ±3.20%
streams/writable-manywrites.js len=32768 callback='no' writev='yes' sync='yes' n=100000 * -1.58 % ±1.21% ±1.61% ±2.11%
streams/writable-manywrites.js len=32768 callback='yes' writev='no' sync='no' n=100000 -1.80 % ±2.47% ±3.29% ±4.29%
streams/writable-manywrites.js len=32768 callback='yes' writev='no' sync='yes' n=100000 -0.50 % ±0.59% ±0.79% ±1.03%
streams/writable-manywrites.js len=32768 callback='yes' writev='yes' sync='no' n=100000 ** -2.81 % ±1.87% ±2.49% ±3.25%
streams/writable-manywrites.js len=32768 callback='yes' writev='yes' sync='yes' n=100000 0.52 % ±1.84% ±2.47% ±3.26%
streams/writable-uint8array.js kind='object-mode' n=50000000 0.21 % ±0.41% ±0.55% ±0.72%
streams/writable-uint8array.js kind='write' n=50000000 -0.28 % ±0.47% ±0.63% ±0.82%
streams/writable-uint8array.js kind='writev' n=50000000 * 0.41 % ±0.32% ±0.43% ±0.56%
Be aware that when doing many comparisons the risk of a false-positive
result increases. In this case, there are 43 comparisons, you can thus
expect the following amount of false-positive results:
2.15 false positives, when considering a 5% risk acceptance (*, **, ***),
0.43 false positives, when considering a 1% risk acceptance (**, ***),
0.04 false positives, when considering a 0.1% risk acceptance (***)