Skip to content

Commit 9cf8c68

Browse files
committed
events: optimize performance of add, remove, emit
If more than one handler is bound to an event type, avoid copying it on emit and instead set a flag that regulates whether to make a copy when a new event is added or removed. Do not use delete or Object.create(null) when removing listeners, instead set to undefined and modify other methods to account for this.
1 parent 4503da8 commit 9cf8c68

File tree

10 files changed

+243
-94
lines changed

10 files changed

+243
-94
lines changed

benchmark/events/ee-add-remove.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,30 @@
22
const common = require('../common.js');
33
const events = require('events');
44

5-
const bench = common.createBenchmark(main, { n: [25e4] });
5+
const bench = common.createBenchmark(main, {
6+
n: [5e6],
7+
events: [0, 5],
8+
listeners: [1, 5]
9+
});
610

711
function main(conf) {
8-
const n = conf.n | 0;
12+
let n = conf.n | 0;
13+
const eventsCOunt = conf.events | 0;
14+
const listenersCount = conf.listeners | 0;
915

1016
const ee = new events.EventEmitter();
1117
const listeners = [];
1218

19+
if (listenersCount === 1)
20+
n *= 2;
21+
1322
var k;
14-
for (k = 0; k < 10; k += 1)
23+
for (k = 0; k < listenersCount; k += 1)
1524
listeners.push(function() {});
1625

26+
for (k = 0; k < eventsCOunt; k++)
27+
ee.on(`dummyunused${k}`, () => {});
28+
1729
bench.start();
1830
for (var i = 0; i < n; i += 1) {
1931
const dummy = (i % 2 === 0) ? 'dummy0' : 'dummy1';

benchmark/events/ee-emit-multi.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const EventEmitter = require('events').EventEmitter;
4+
5+
const bench = common.createBenchmark(main, {
6+
n: [2e7],
7+
listeners: [1, 5, 10],
8+
});
9+
10+
function main(conf) {
11+
var n = conf.n | 0;
12+
const listeners = Math.max(conf.listeners | 0, 1);
13+
14+
const ee = new EventEmitter();
15+
16+
if (listeners === 1)
17+
n *= 5;
18+
else if (listeners === 5)
19+
n *= 2;
20+
21+
for (var k = 0; k < listeners; k += 1) {
22+
ee.on('dummy', function() {});
23+
ee.on(`dummy${k}`, function() {});
24+
}
25+
26+
bench.start();
27+
for (var i = 0; i < n; i += 1) {
28+
if (i % 3 === 0)
29+
ee.emit('dummy', true, 5);
30+
else if (i % 2 === 0)
31+
ee.emit('dummy', true, 5, 10, false);
32+
else
33+
ee.emit('dummy');
34+
}
35+
bench.end(n);
36+
}

benchmark/events/ee-emit.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,27 @@ const common = require('../common.js');
33
const EventEmitter = require('events').EventEmitter;
44

55
const bench = common.createBenchmark(main, {
6-
n: [2e6],
6+
n: [2e7],
77
argc: [0, 2, 4, 10],
88
listeners: [1, 5, 10],
99
});
1010

1111
function main(conf) {
12-
const n = conf.n | 0;
12+
var n = conf.n | 0;
1313
const argc = conf.argc | 0;
1414
const listeners = Math.max(conf.listeners | 0, 1);
1515

1616
const ee = new EventEmitter();
1717

18-
for (var k = 0; k < listeners; k += 1)
18+
if (listeners === 1)
19+
n *= 5;
20+
else if (listeners === 5)
21+
n *= 2;
22+
23+
for (var k = 0; k < listeners; k += 1) {
1924
ee.on('dummy', function() {});
25+
ee.on(`dummy${k}`, function() {});
26+
}
2027

2128
var i;
2229
switch (argc) {

benchmark/events/ee-event-names.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const EventEmitter = require('events').EventEmitter;
4+
5+
const bench = common.createBenchmark(main, {
6+
n: [1e6],
7+
listeners: [1, 10],
8+
symbols: ['true', 'false']
9+
});
10+
11+
function main(conf) {
12+
const n = conf.n | 0;
13+
const listeners = conf.listeners | 0;
14+
const useSymbols = conf.symbols === 'true';
15+
16+
const ee = new EventEmitter();
17+
18+
for (var k = 0; k < listeners; k += 1) {
19+
ee.on(`dummy0${k}`, function() {});
20+
ee.on(`dummy1${k}`, function() {});
21+
ee.on(`dummy2${k}`, function() {});
22+
if (useSymbols)
23+
ee.on(Symbol(`dummy${k}`), function() {});
24+
}
25+
26+
ee.removeAllListeners('dummy01');
27+
ee.removeAllListeners('dummy11');
28+
ee.removeAllListeners('dummy21');
29+
ee.removeAllListeners('dummy06');
30+
ee.removeAllListeners('dummy16');
31+
ee.removeAllListeners('dummy26');
32+
33+
bench.start();
34+
for (var i = 0; i < n; i += 1) {
35+
ee.eventNames();
36+
}
37+
bench.end(n);
38+
}

benchmark/events/ee-listeners-many.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
const common = require('../common.js');
33
const EventEmitter = require('events').EventEmitter;
44

5-
const bench = common.createBenchmark(main, { n: [5e6] });
5+
const bench = common.createBenchmark(main, { n: [1e7] });
66

77
function main(conf) {
88
const n = conf.n | 0;

benchmark/events/ee-listeners.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
const common = require('../common.js');
33
const EventEmitter = require('events').EventEmitter;
44

5-
const bench = common.createBenchmark(main, { n: [5e6] });
5+
const bench = common.createBenchmark(main, { n: [5e7] });
66

77
function main(conf) {
88
const n = conf.n | 0;

benchmark/events/ee-once.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,27 @@
22
const common = require('../common.js');
33
const EventEmitter = require('events').EventEmitter;
44

5-
const bench = common.createBenchmark(main, { n: [2e7] });
5+
const bench = common.createBenchmark(main, {
6+
n: [5e6],
7+
listeners: [1, 5]
8+
});
69

710
function main(conf) {
8-
const n = conf.n | 0;
11+
let n = conf.n | 0;
12+
const listeners = conf.listeners | 0;
13+
14+
if (listeners === 1)
15+
n *= 2;
916

1017
const ee = new EventEmitter();
1118

1219
function listener() {}
1320

1421
bench.start();
15-
for (var i = 0; i < n; i += 1) {
22+
for (var i = 0; i < n; ++i) {
1623
const dummy = (i % 2 === 0) ? 'dummy0' : 'dummy1';
17-
ee.once(dummy, listener);
24+
for (var j = 0; j < listeners; ++j)
25+
ee.once(dummy, listener);
1826
ee.emit(dummy);
1927
}
2028
bench.end(n);

0 commit comments

Comments
 (0)