Skip to content

Commit

Permalink
events: improve performance caused by primordials
Browse files Browse the repository at this point in the history
PR-URL: #30577
Refs: nodejs/code-and-learn#97
Refs: #29766
Refs: #29633
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Yongsheng Zhang <[email protected]>
Reviewed-By: Gireesh Punathil <[email protected]>
  • Loading branch information
antimonyGu authored and addaleax committed Nov 30, 2019
1 parent 4e5818a commit 0285aa0
Showing 1 changed file with 29 additions and 16 deletions.
45 changes: 29 additions & 16 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,21 @@

'use strict';

const { Math, Object, Reflect } = primordials;
const apply = Reflect.apply;
const {
Math: {
min: MathMin
},
Object: {
defineProperty: ObjectDefineProperty,
getPrototypeOf: ObjectGetPrototypeOf,
create: ObjectCreate,
keys: ObjectKeys,
},
Reflect: {
apply: ReflectApply,
ownKeys: ReflectOwnKeys,
}
} = primordials;

var spliceOne;

Expand Down Expand Up @@ -65,7 +78,7 @@ function checkListener(listener) {
}
}

Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
ObjectDefineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
Expand All @@ -83,8 +96,8 @@ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
EventEmitter.init = function() {

if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._events === ObjectGetPrototypeOf(this)._events) {
this._events = ObjectCreate(null);
this._eventsCount = 0;
}

Expand Down Expand Up @@ -121,7 +134,7 @@ function identicalSequenceRange(a, b) {
const rest = b.length - pos;
if (rest > 3) {
let len = 1;
const maxLen = Math.min(a.length - i, rest);
const maxLen = MathMin(a.length - i, rest);
// Count the number of consecutive entries.
while (maxLen > len && a[i + len] === b[pos + len]) {
len++;
Expand Down Expand Up @@ -176,7 +189,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
const capture = {};
// eslint-disable-next-line no-restricted-syntax
Error.captureStackTrace(capture, EventEmitter.prototype.emit);
Object.defineProperty(er, kEnhanceStackBeforeInspector, {
ObjectDefineProperty(er, kEnhanceStackBeforeInspector, {
value: enhanceStackTrace.bind(this, er, capture),
configurable: true
});
Expand Down Expand Up @@ -207,12 +220,12 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
return false;

if (typeof handler === 'function') {
apply(handler, this, args);
ReflectApply(handler, this, args);
} else {
const len = handler.length;
const listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
apply(listeners[i], this, args);
ReflectApply(listeners[i], this, args);
}

return true;
Expand All @@ -227,7 +240,7 @@ function _addListener(target, type, listener, prepend) {

events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
events = target._events = ObjectCreate(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
Expand Down Expand Up @@ -341,7 +354,7 @@ EventEmitter.prototype.removeListener =

if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
this._events = ObjectCreate(null);
else {
delete events[type];
if (events.removeListener)
Expand Down Expand Up @@ -390,11 +403,11 @@ EventEmitter.prototype.removeAllListeners =
// Not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._events = ObjectCreate(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
this._events = ObjectCreate(null);
else
delete events[type];
}
Expand All @@ -403,12 +416,12 @@ EventEmitter.prototype.removeAllListeners =

// Emit removeListener for all listeners on all events
if (arguments.length === 0) {
for (const key of Object.keys(events)) {
for (const key of ObjectKeys(events)) {
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._events = ObjectCreate(null);
this._eventsCount = 0;
return this;
}
Expand Down Expand Up @@ -478,7 +491,7 @@ function listenerCount(type) {
}

EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};

function arrayClone(arr, n) {
Expand Down

0 comments on commit 0285aa0

Please sign in to comment.