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);
|
||||
};
|
||||
|
||||
function _onceWrap(target, type, listener) {
|
||||
var fired = false;
|
||||
function g() {
|
||||
target.removeListener(type, g);
|
||||
if (!fired) {
|
||||
fired = true;
|
||||
listener.apply(target, arguments);
|
||||
}
|
||||
function onceWrapper() {
|
||||
this.target.removeListener(this.type, this.wrapFn);
|
||||
if (!this.fired) {
|
||||
this.fired = true;
|
||||
this.listener.apply(this.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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user