events: stricter prop & variable checks for perf
Replace truthy/falsey checks of _events and _events[type] with comparisons to undefined for better performance: events/ee-add-remove.js n=250000 5.30 % *** 4.260028e-07 events/ee-emit.js n=2000000 4.18 % *** 1.026649e-05 This has a knock-on effect on modules that use lots of events, e.g.: http2/headers.js nheaders=0 n=1000 2.60 % *** 0.000298338 PR-URL: https://github.com/nodejs/node/pull/16212 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
parent
6d4c68523d
commit
f61cc15c6a
@ -78,7 +78,8 @@ EventEmitter.init = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
|
if (this._events === undefined ||
|
||||||
|
this._events === Object.getPrototypeOf(this)._events) {
|
||||||
this._events = Object.create(null);
|
this._events = Object.create(null);
|
||||||
this._eventsCount = 0;
|
this._eventsCount = 0;
|
||||||
}
|
}
|
||||||
@ -170,8 +171,8 @@ EventEmitter.prototype.emit = function emit(type) {
|
|||||||
var doError = (type === 'error');
|
var doError = (type === 'error');
|
||||||
|
|
||||||
events = this._events;
|
events = this._events;
|
||||||
if (events)
|
if (events !== undefined)
|
||||||
doError = (doError && events.error == null);
|
doError = (doError && events.error === undefined);
|
||||||
else if (!doError)
|
else if (!doError)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -181,7 +182,7 @@ EventEmitter.prototype.emit = function emit(type) {
|
|||||||
if (doError) {
|
if (doError) {
|
||||||
if (arguments.length > 1)
|
if (arguments.length > 1)
|
||||||
er = arguments[1];
|
er = arguments[1];
|
||||||
if (domain) {
|
if (domain !== null && domain !== undefined) {
|
||||||
if (!er) {
|
if (!er) {
|
||||||
const errors = lazyErrors();
|
const errors = lazyErrors();
|
||||||
er = new errors.Error('ERR_UNHANDLED_ERROR');
|
er = new errors.Error('ERR_UNHANDLED_ERROR');
|
||||||
@ -206,10 +207,10 @@ EventEmitter.prototype.emit = function emit(type) {
|
|||||||
|
|
||||||
handler = events[type];
|
handler = events[type];
|
||||||
|
|
||||||
if (!handler)
|
if (handler === undefined)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (domain && this !== process) {
|
if (domain !== null && domain !== undefined && this !== process) {
|
||||||
domain.enter();
|
domain.enter();
|
||||||
needDomainExit = true;
|
needDomainExit = true;
|
||||||
}
|
}
|
||||||
@ -255,13 +256,13 @@ function _addListener(target, type, listener, prepend) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
events = target._events;
|
events = target._events;
|
||||||
if (!events) {
|
if (events === undefined) {
|
||||||
events = target._events = Object.create(null);
|
events = target._events = Object.create(null);
|
||||||
target._eventsCount = 0;
|
target._eventsCount = 0;
|
||||||
} else {
|
} else {
|
||||||
// To avoid recursion in the case that type === "newListener"! Before
|
// To avoid recursion in the case that type === "newListener"! Before
|
||||||
// adding it to the listeners, first emit "newListener".
|
// adding it to the listeners, first emit "newListener".
|
||||||
if (events.newListener) {
|
if (events.newListener !== undefined) {
|
||||||
target.emit('newListener', type,
|
target.emit('newListener', type,
|
||||||
listener.listener ? listener.listener : listener);
|
listener.listener ? listener.listener : listener);
|
||||||
|
|
||||||
@ -272,7 +273,7 @@ function _addListener(target, type, listener, prepend) {
|
|||||||
existing = events[type];
|
existing = events[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existing) {
|
if (existing === undefined) {
|
||||||
// Optimize the case of one listener. Don't need the extra array object.
|
// Optimize the case of one listener. Don't need the extra array object.
|
||||||
existing = events[type] = listener;
|
existing = events[type] = listener;
|
||||||
++target._eventsCount;
|
++target._eventsCount;
|
||||||
@ -384,11 +385,11 @@ EventEmitter.prototype.removeListener =
|
|||||||
}
|
}
|
||||||
|
|
||||||
events = this._events;
|
events = this._events;
|
||||||
if (!events)
|
if (events === undefined)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
list = events[type];
|
list = events[type];
|
||||||
if (!list)
|
if (list === undefined)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (list === listener || list.listener === listener) {
|
if (list === listener || list.listener === listener) {
|
||||||
@ -424,7 +425,7 @@ EventEmitter.prototype.removeListener =
|
|||||||
if (list.length === 1)
|
if (list.length === 1)
|
||||||
events[type] = list[0];
|
events[type] = list[0];
|
||||||
|
|
||||||
if (events.removeListener)
|
if (events.removeListener !== undefined)
|
||||||
this.emit('removeListener', type, originalListener || listener);
|
this.emit('removeListener', type, originalListener || listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,15 +437,15 @@ EventEmitter.prototype.removeAllListeners =
|
|||||||
var listeners, events, i;
|
var listeners, events, i;
|
||||||
|
|
||||||
events = this._events;
|
events = this._events;
|
||||||
if (!events)
|
if (events === undefined)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
// not listening for removeListener, no need to emit
|
// not listening for removeListener, no need to emit
|
||||||
if (!events.removeListener) {
|
if (events.removeListener === undefined) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
this._events = Object.create(null);
|
this._events = Object.create(null);
|
||||||
this._eventsCount = 0;
|
this._eventsCount = 0;
|
||||||
} else if (events[type]) {
|
} else if (events[type] !== undefined) {
|
||||||
if (--this._eventsCount === 0)
|
if (--this._eventsCount === 0)
|
||||||
this._events = Object.create(null);
|
this._events = Object.create(null);
|
||||||
else
|
else
|
||||||
@ -472,7 +473,7 @@ EventEmitter.prototype.removeAllListeners =
|
|||||||
|
|
||||||
if (typeof listeners === 'function') {
|
if (typeof listeners === 'function') {
|
||||||
this.removeListener(type, listeners);
|
this.removeListener(type, listeners);
|
||||||
} else if (listeners) {
|
} else if (listeners !== undefined) {
|
||||||
// LIFO order
|
// LIFO order
|
||||||
for (i = listeners.length - 1; i >= 0; i--) {
|
for (i = listeners.length - 1; i >= 0; i--) {
|
||||||
this.removeListener(type, listeners[i]);
|
this.removeListener(type, listeners[i]);
|
||||||
@ -487,11 +488,11 @@ EventEmitter.prototype.listeners = function listeners(type) {
|
|||||||
var ret;
|
var ret;
|
||||||
var events = this._events;
|
var events = this._events;
|
||||||
|
|
||||||
if (!events)
|
if (events === undefined)
|
||||||
ret = [];
|
ret = [];
|
||||||
else {
|
else {
|
||||||
evlistener = events[type];
|
evlistener = events[type];
|
||||||
if (!evlistener)
|
if (evlistener === undefined)
|
||||||
ret = [];
|
ret = [];
|
||||||
else if (typeof evlistener === 'function')
|
else if (typeof evlistener === 'function')
|
||||||
ret = [evlistener.listener || evlistener];
|
ret = [evlistener.listener || evlistener];
|
||||||
@ -514,12 +515,12 @@ EventEmitter.prototype.listenerCount = listenerCount;
|
|||||||
function listenerCount(type) {
|
function listenerCount(type) {
|
||||||
const events = this._events;
|
const events = this._events;
|
||||||
|
|
||||||
if (events) {
|
if (events !== undefined) {
|
||||||
const evlistener = events[type];
|
const evlistener = events[type];
|
||||||
|
|
||||||
if (typeof evlistener === 'function') {
|
if (typeof evlistener === 'function') {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (evlistener) {
|
} else if (evlistener !== undefined) {
|
||||||
return evlistener.length;
|
return evlistener.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user