events: improve once() performance
This commit takes advantage of the performance improvements V8 has made to function.bind() in V8 5.4 and uses it to avoid constant recompilation/reoptimization of the wrapper closure used in once(). This change results in ~27% performance increase for once(). PR-URL: https://github.com/nodejs/node/pull/10445 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Teddy Katz <teddy.katz@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
627fa93095
commit
4c9dd6822e
20
benchmark/events/ee-once.js
Normal file
20
benchmark/events/ee-once.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
var common = require('../common.js');
|
||||||
|
var EventEmitter = require('events').EventEmitter;
|
||||||
|
|
||||||
|
var bench = common.createBenchmark(main, {n: [2e7]});
|
||||||
|
|
||||||
|
function main(conf) {
|
||||||
|
var n = conf.n | 0;
|
||||||
|
|
||||||
|
var ee = new EventEmitter();
|
||||||
|
|
||||||
|
function listener() {}
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (var i = 0; i < n; i += 1) {
|
||||||
|
ee.once('dummy', listener);
|
||||||
|
ee.emit('dummy');
|
||||||
|
}
|
||||||
|
bench.end(n);
|
||||||
|
}
|
@ -283,17 +283,20 @@ EventEmitter.prototype.prependListener =
|
|||||||
return _addListener(this, type, listener, true);
|
return _addListener(this, type, listener, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
function _onceWrap(target, type, listener) {
|
function onceWrapper() {
|
||||||
var fired = false;
|
this.target.removeListener(this.type, this.wrapFn);
|
||||||
function g() {
|
if (!this.fired) {
|
||||||
target.removeListener(type, g);
|
this.fired = true;
|
||||||
if (!fired) {
|
this.listener.apply(this.target, arguments);
|
||||||
fired = true;
|
|
||||||
listener.apply(target, arguments);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
g.listener = listener;
|
}
|
||||||
return g;
|
|
||||||
|
function _onceWrap(target, type, listener) {
|
||||||
|
var state = { fired: false, wrapFn: undefined, target, type, listener };
|
||||||
|
var wrapped = onceWrapper.bind(state);
|
||||||
|
wrapped.listener = listener;
|
||||||
|
state.wrapFn = wrapped;
|
||||||
|
return wrapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventEmitter.prototype.once = function once(type, listener) {
|
EventEmitter.prototype.once = function once(type, listener) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user