Skip to content

Commit 3e38006

Browse files
committed
events: improve eventEmitter.once() performance
This commit improves once() performance by avoiding the creation of wrapper functions. These changes bring ~51% increase in performance when simply adding once() event handlers, ~205% increase in the included ee-emit-once benchmark, and a ~36% increase in the included ee-add-remove-once benchmark. This commit also adds new benchmarks, bumps the default number of iterations for several of the existing benchmarks, and also adds missing forced optimizations.
1 parent 4ed0388 commit 3e38006

20 files changed

+871
-196
lines changed

benchmark/events/ee-add-once.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [50e6]
9+
});
10+
11+
function main(conf) {
12+
var n = +conf.n;
13+
var ee = new EventEmitter();
14+
var listeners = [];
15+
16+
var k;
17+
for (k = 0; k < 10; k += 1)
18+
listeners.push(function() {});
19+
20+
// Force optimization before starting the benchmark
21+
ee.once('dummy', listeners[0]);
22+
ee._events = {};
23+
v8.setFlagsFromString('--allow_natives_syntax');
24+
eval('%OptimizeFunctionOnNextCall(ee.once)');
25+
ee.once('dummy', listeners[0]);
26+
ee._events = {};
27+
28+
bench.start();
29+
for (var i = 0; i < n; ++i) {
30+
for (k = listeners.length; --k >= 0; /* empty */)
31+
ee.once('dummy', listeners[k]);
32+
ee._events = {};
33+
}
34+
bench.end(n);
35+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [25e6]
9+
});
10+
11+
function main(conf) {
12+
var n = conf.n | 0;
13+
14+
var ee = new EventEmitter();
15+
var listeners = [];
16+
17+
var k;
18+
for (k = 0; k < 10; k += 1)
19+
listeners.push(function() {});
20+
21+
for (k = listeners.length; --k >= 0; /* empty */)
22+
ee.once('dummy', listeners[k]);
23+
for (k = listeners.length; --k >= 0; /* empty */)
24+
ee.removeListener('dummy', listeners[k]);
25+
v8.setFlagsFromString('--allow_natives_syntax');
26+
eval('%OptimizeFunctionOnNextCall(ee.once)');
27+
eval('%OptimizeFunctionOnNextCall(ee.removeListener)');
28+
for (k = listeners.length; --k >= 0; /* empty */)
29+
ee.once('dummy', listeners[k]);
30+
for (k = listeners.length; --k >= 0; /* empty */)
31+
ee.removeListener('dummy', listeners[k]);
32+
33+
bench.start();
34+
for (var i = 0; i < n; i += 1) {
35+
for (k = listeners.length; --k >= 0; /* empty */)
36+
ee.once('dummy', listeners[k]);
37+
for (k = listeners.length; --k >= 0; /* empty */)
38+
ee.removeListener('dummy', listeners[k]);
39+
}
40+
bench.end(n);
41+
}

benchmark/events/ee-add-remove.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,35 @@
11
'use strict';
2-
var common = require('../common.js');
3-
var events = require('events');
42

5-
var bench = common.createBenchmark(main, {n: [25e4]});
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [50e5]
9+
});
610

711
function main(conf) {
812
var n = conf.n | 0;
913

10-
var ee = new events.EventEmitter();
14+
var ee = new EventEmitter();
1115
var listeners = [];
1216

1317
var k;
1418
for (k = 0; k < 10; k += 1)
1519
listeners.push(function() {});
1620

21+
for (k = listeners.length; --k >= 0; /* empty */)
22+
ee.on('dummy', listeners[k]);
23+
for (k = listeners.length; --k >= 0; /* empty */)
24+
ee.removeListener('dummy', listeners[k]);
25+
v8.setFlagsFromString('--allow_natives_syntax');
26+
eval('%OptimizeFunctionOnNextCall(ee.on)');
27+
eval('%OptimizeFunctionOnNextCall(ee.removeListener)');
28+
for (k = listeners.length; --k >= 0; /* empty */)
29+
ee.on('dummy', listeners[k]);
30+
for (k = listeners.length; --k >= 0; /* empty */)
31+
ee.removeListener('dummy', listeners[k]);
32+
1733
bench.start();
1834
for (var i = 0; i < n; i += 1) {
1935
for (k = listeners.length; --k >= 0; /* empty */)

benchmark/events/ee-add.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [100e5]
9+
});
10+
11+
function main(conf) {
12+
var n = +conf.n;
13+
var ee = new EventEmitter();
14+
var listeners = [];
15+
16+
var k;
17+
for (k = 0; k < 10; k += 1)
18+
listeners.push(function() {});
19+
20+
// Force optimization before starting the benchmark
21+
ee.on('dummy', listeners[0]);
22+
ee._events = {};
23+
v8.setFlagsFromString('--allow_natives_syntax');
24+
eval('%OptimizeFunctionOnNextCall(ee.on)');
25+
ee.on('dummy', listeners[0]);
26+
ee._events = {};
27+
28+
bench.start();
29+
for (var i = 0; i < n; ++i) {
30+
for (k = listeners.length; --k >= 0; /* empty */)
31+
ee.on('dummy', listeners[k]);
32+
ee._events = {};
33+
}
34+
bench.end(n);
35+
}

benchmark/events/ee-emit-multi-args.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
'use strict';
2-
var common = require('../common.js');
3-
var EventEmitter = require('events').EventEmitter;
42

5-
var bench = common.createBenchmark(main, {n: [2e6]});
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [25e6]
9+
});
610

711
function main(conf) {
812
var n = conf.n | 0;
@@ -12,6 +16,11 @@ function main(conf) {
1216
for (var k = 0; k < 10; k += 1)
1317
ee.on('dummy', function() {});
1418

19+
ee.emit('dummy', 5, true);
20+
v8.setFlagsFromString('--allow_natives_syntax');
21+
eval('%OptimizeFunctionOnNextCall(ee.emit)');
22+
ee.emit('dummy', 5, true);
23+
1524
bench.start();
1625
for (var i = 0; i < n; i += 1) {
1726
ee.emit('dummy', 5, true);

benchmark/events/ee-emit-once.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
'use strict';
2+
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [25e6]
9+
});
10+
11+
function main(conf) {
12+
var n = conf.n | 0;
13+
14+
var ee = new EventEmitter();
15+
16+
function noop() {}
17+
18+
ee.once('dummy', noop);
19+
ee.emit('dummy');
20+
v8.setFlagsFromString('--allow_natives_syntax');
21+
eval('%OptimizeFunctionOnNextCall(ee.once)');
22+
eval('%OptimizeFunctionOnNextCall(ee.emit)');
23+
ee.once('dummy', noop);
24+
ee.emit('dummy');
25+
26+
bench.start();
27+
for (var i = 0; i < n; i += 1) {
28+
ee.once('dummy', noop);
29+
ee.emit('dummy');
30+
}
31+
bench.end(n);
32+
}

benchmark/events/ee-emit.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
'use strict';
2-
var common = require('../common.js');
3-
var EventEmitter = require('events').EventEmitter;
42

5-
var bench = common.createBenchmark(main, {n: [2e6]});
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [50e6]
9+
});
610

711
function main(conf) {
812
var n = conf.n | 0;
@@ -12,6 +16,11 @@ function main(conf) {
1216
for (var k = 0; k < 10; k += 1)
1317
ee.on('dummy', function() {});
1418

19+
ee.emit('dummy');
20+
v8.setFlagsFromString('--allow_natives_syntax');
21+
eval('%OptimizeFunctionOnNextCall(ee.emit)');
22+
ee.emit('dummy');
23+
1524
bench.start();
1625
for (var i = 0; i < n; i += 1) {
1726
ee.emit('dummy');

benchmark/events/ee-listener-count-on-prototype.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
'use strict';
2-
var common = require('../common.js');
3-
var EventEmitter = require('events').EventEmitter;
42

5-
var bench = common.createBenchmark(main, {n: [5e7]});
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [5e7]
9+
});
610

711
function main(conf) {
812
var n = conf.n | 0;
@@ -12,6 +16,11 @@ function main(conf) {
1216
for (var k = 0; k < 10; k += 1)
1317
ee.on('dummy', function() {});
1418

19+
ee.listenerCount('dummy');
20+
v8.setFlagsFromString('--allow_natives_syntax');
21+
eval('%OptimizeFunctionOnNextCall(ee.listenerCount)');
22+
ee.listenerCount('dummy');
23+
1524
bench.start();
1625
for (var i = 0; i < n; i += 1) {
1726
ee.listenerCount('dummy');

benchmark/events/ee-listeners-many.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
'use strict';
2-
var common = require('../common.js');
3-
var EventEmitter = require('events').EventEmitter;
42

5-
var bench = common.createBenchmark(main, {n: [5e6]});
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [15e6]
9+
});
610

711
function main(conf) {
812
var n = conf.n | 0;
@@ -13,6 +17,11 @@ function main(conf) {
1317
for (var k = 0; k < 100; k += 1)
1418
ee.on('dummy', function() {});
1519

20+
ee.listeners('dummy');
21+
v8.setFlagsFromString('--allow_natives_syntax');
22+
eval('%OptimizeFunctionOnNextCall(ee.listeners)');
23+
ee.listeners('dummy');
24+
1625
bench.start();
1726
for (var i = 0; i < n; i += 1) {
1827
ee.listeners('dummy');

benchmark/events/ee-listeners.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
'use strict';
2-
var common = require('../common.js');
3-
var EventEmitter = require('events').EventEmitter;
42

5-
var bench = common.createBenchmark(main, {n: [5e6]});
3+
var common = require('../common');
4+
var EventEmitter = require('events');
5+
var v8 = require('v8');
6+
7+
var bench = common.createBenchmark(main, {
8+
n: [90e6]
9+
});
610

711
function main(conf) {
812
var n = conf.n | 0;
@@ -12,6 +16,11 @@ function main(conf) {
1216
for (var k = 0; k < 10; k += 1)
1317
ee.on('dummy', function() {});
1418

19+
ee.listeners('dummy');
20+
v8.setFlagsFromString('--allow_natives_syntax');
21+
eval('%OptimizeFunctionOnNextCall(ee.listeners)');
22+
ee.listeners('dummy');
23+
1524
bench.start();
1625
for (var i = 0; i < n; i += 1) {
1726
ee.listeners('dummy');

0 commit comments

Comments
 (0)