Skip to content

Commit

Permalink
events: stricter prop & variable checks for perf
Browse files Browse the repository at this point in the history
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: #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>
  • Loading branch information
apapirovski committed Oct 21, 2017
1 parent 6d4c685 commit f61cc15
Showing 1 changed file with 21 additions and 20 deletions.
41 changes: 21 additions & 20 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ EventEmitter.init = function() {
}
}

if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
if (this._events === undefined ||

This comment has been minimized.

Copy link
@AnthonyYY

AnthonyYY Jun 2, 2018

why this if statement is required, any init only execute once right? so this.event must be undefined right? oh can someone explain this for me

this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
Expand Down Expand Up @@ -170,8 +171,8 @@ EventEmitter.prototype.emit = function emit(type) {
var doError = (type === 'error');

events = this._events;
if (events)
doError = (doError && events.error == null);
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;

Expand All @@ -181,7 +182,7 @@ EventEmitter.prototype.emit = function emit(type) {
if (doError) {
if (arguments.length > 1)
er = arguments[1];
if (domain) {
if (domain !== null && domain !== undefined) {
if (!er) {
const errors = lazyErrors();
er = new errors.Error('ERR_UNHANDLED_ERROR');
Expand All @@ -206,10 +207,10 @@ EventEmitter.prototype.emit = function emit(type) {

handler = events[type];

if (!handler)
if (handler === undefined)
return false;

if (domain && this !== process) {
if (domain !== null && domain !== undefined && this !== process) {
domain.enter();
needDomainExit = true;
}
Expand Down Expand Up @@ -255,13 +256,13 @@ function _addListener(target, type, listener, prepend) {
}

events = target._events;
if (!events) {
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener) {
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);

Expand All @@ -272,7 +273,7 @@ function _addListener(target, type, listener, prepend) {
existing = events[type];
}

if (!existing) {
if (existing === undefined) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
Expand Down Expand Up @@ -384,11 +385,11 @@ EventEmitter.prototype.removeListener =
}

events = this._events;
if (!events)
if (events === undefined)
return this;

list = events[type];
if (!list)
if (list === undefined)
return this;

if (list === listener || list.listener === listener) {
Expand Down Expand Up @@ -424,7 +425,7 @@ EventEmitter.prototype.removeListener =
if (list.length === 1)
events[type] = list[0];

if (events.removeListener)
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}

Expand All @@ -436,15 +437,15 @@ EventEmitter.prototype.removeAllListeners =
var listeners, events, i;

events = this._events;
if (!events)
if (events === undefined)
return this;

// not listening for removeListener, no need to emit
if (!events.removeListener) {
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type]) {
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
Expand Down Expand Up @@ -472,7 +473,7 @@ EventEmitter.prototype.removeAllListeners =

if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners) {
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
Expand All @@ -487,11 +488,11 @@ EventEmitter.prototype.listeners = function listeners(type) {
var ret;
var events = this._events;

if (!events)
if (events === undefined)
ret = [];
else {
evlistener = events[type];
if (!evlistener)
if (evlistener === undefined)
ret = [];
else if (typeof evlistener === 'function')
ret = [evlistener.listener || evlistener];
Expand All @@ -514,12 +515,12 @@ EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
const events = this._events;

if (events) {
if (events !== undefined) {
const evlistener = events[type];

if (typeof evlistener === 'function') {
return 1;
} else if (evlistener) {
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
Expand Down

0 comments on commit f61cc15

Please sign in to comment.