Skip to content

Commit

Permalink
events: improve eventEmitter.once() performance
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mscdex committed Mar 8, 2016
1 parent 4ed0388 commit 3e38006
Show file tree
Hide file tree
Showing 20 changed files with 871 additions and 196 deletions.
35 changes: 35 additions & 0 deletions benchmark/events/ee-add-once.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [50e6]
});

function main(conf) {
var n = +conf.n;
var ee = new EventEmitter();
var listeners = [];

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

// Force optimization before starting the benchmark
ee.once('dummy', listeners[0]);
ee._events = {};
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.once)');
ee.once('dummy', listeners[0]);
ee._events = {};

bench.start();
for (var i = 0; i < n; ++i) {
for (k = listeners.length; --k >= 0; /* empty */)
ee.once('dummy', listeners[k]);
ee._events = {};
}
bench.end(n);
}
41 changes: 41 additions & 0 deletions benchmark/events/ee-add-remove-once.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [25e6]
});

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

var ee = new EventEmitter();
var listeners = [];

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

for (k = listeners.length; --k >= 0; /* empty */)
ee.once('dummy', listeners[k]);
for (k = listeners.length; --k >= 0; /* empty */)
ee.removeListener('dummy', listeners[k]);
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.once)');
eval('%OptimizeFunctionOnNextCall(ee.removeListener)');
for (k = listeners.length; --k >= 0; /* empty */)
ee.once('dummy', listeners[k]);
for (k = listeners.length; --k >= 0; /* empty */)
ee.removeListener('dummy', listeners[k]);

bench.start();
for (var i = 0; i < n; i += 1) {
for (k = listeners.length; --k >= 0; /* empty */)
ee.once('dummy', listeners[k]);
for (k = listeners.length; --k >= 0; /* empty */)
ee.removeListener('dummy', listeners[k]);
}
bench.end(n);
}
24 changes: 20 additions & 4 deletions benchmark/events/ee-add-remove.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,35 @@
'use strict';
var common = require('../common.js');
var events = require('events');

var bench = common.createBenchmark(main, {n: [25e4]});
var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [50e5]
});

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

var ee = new events.EventEmitter();
var ee = new EventEmitter();
var listeners = [];

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

for (k = listeners.length; --k >= 0; /* empty */)
ee.on('dummy', listeners[k]);
for (k = listeners.length; --k >= 0; /* empty */)
ee.removeListener('dummy', listeners[k]);
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.on)');
eval('%OptimizeFunctionOnNextCall(ee.removeListener)');
for (k = listeners.length; --k >= 0; /* empty */)
ee.on('dummy', listeners[k]);
for (k = listeners.length; --k >= 0; /* empty */)
ee.removeListener('dummy', listeners[k]);

bench.start();
for (var i = 0; i < n; i += 1) {
for (k = listeners.length; --k >= 0; /* empty */)
Expand Down
35 changes: 35 additions & 0 deletions benchmark/events/ee-add.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
'use strict';

var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [100e5]
});

function main(conf) {
var n = +conf.n;
var ee = new EventEmitter();
var listeners = [];

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

// Force optimization before starting the benchmark
ee.on('dummy', listeners[0]);
ee._events = {};
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.on)');
ee.on('dummy', listeners[0]);
ee._events = {};

bench.start();
for (var i = 0; i < n; ++i) {
for (k = listeners.length; --k >= 0; /* empty */)
ee.on('dummy', listeners[k]);
ee._events = {};
}
bench.end(n);
}
15 changes: 12 additions & 3 deletions benchmark/events/ee-emit-multi-args.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
'use strict';
var common = require('../common.js');
var EventEmitter = require('events').EventEmitter;

var bench = common.createBenchmark(main, {n: [2e6]});
var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [25e6]
});

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

ee.emit('dummy', 5, true);
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.emit)');
ee.emit('dummy', 5, true);

bench.start();
for (var i = 0; i < n; i += 1) {
ee.emit('dummy', 5, true);
Expand Down
32 changes: 32 additions & 0 deletions benchmark/events/ee-emit-once.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [25e6]
});

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

var ee = new EventEmitter();

function noop() {}

ee.once('dummy', noop);
ee.emit('dummy');
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.once)');
eval('%OptimizeFunctionOnNextCall(ee.emit)');
ee.once('dummy', noop);
ee.emit('dummy');

bench.start();
for (var i = 0; i < n; i += 1) {
ee.once('dummy', noop);
ee.emit('dummy');
}
bench.end(n);
}
15 changes: 12 additions & 3 deletions benchmark/events/ee-emit.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
'use strict';
var common = require('../common.js');
var EventEmitter = require('events').EventEmitter;

var bench = common.createBenchmark(main, {n: [2e6]});
var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [50e6]
});

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

ee.emit('dummy');
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.emit)');
ee.emit('dummy');

bench.start();
for (var i = 0; i < n; i += 1) {
ee.emit('dummy');
Expand Down
15 changes: 12 additions & 3 deletions benchmark/events/ee-listener-count-on-prototype.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
'use strict';
var common = require('../common.js');
var EventEmitter = require('events').EventEmitter;

var bench = common.createBenchmark(main, {n: [5e7]});
var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [5e7]
});

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

ee.listenerCount('dummy');
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.listenerCount)');
ee.listenerCount('dummy');

bench.start();
for (var i = 0; i < n; i += 1) {
ee.listenerCount('dummy');
Expand Down
15 changes: 12 additions & 3 deletions benchmark/events/ee-listeners-many.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
'use strict';
var common = require('../common.js');
var EventEmitter = require('events').EventEmitter;

var bench = common.createBenchmark(main, {n: [5e6]});
var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [15e6]
});

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

ee.listeners('dummy');
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.listeners)');
ee.listeners('dummy');

bench.start();
for (var i = 0; i < n; i += 1) {
ee.listeners('dummy');
Expand Down
15 changes: 12 additions & 3 deletions benchmark/events/ee-listeners.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
'use strict';
var common = require('../common.js');
var EventEmitter = require('events').EventEmitter;

var bench = common.createBenchmark(main, {n: [5e6]});
var common = require('../common');
var EventEmitter = require('events');
var v8 = require('v8');

var bench = common.createBenchmark(main, {
n: [90e6]
});

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

ee.listeners('dummy');
v8.setFlagsFromString('--allow_natives_syntax');
eval('%OptimizeFunctionOnNextCall(ee.listeners)');
ee.listeners('dummy');

bench.start();
for (var i = 0; i < n; i += 1) {
ee.listeners('dummy');
Expand Down
Loading

0 comments on commit 3e38006

Please sign in to comment.