From e5cbbe05ef8d2b9878f153cd0d7d898cd5d75fa8 Mon Sep 17 00:00:00 2001 From: guzhizhou Date: Tue, 19 Nov 2019 20:22:12 +0800 Subject: [PATCH] events: improve performance caused by primordials MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/30577 Refs: https://github.com/nodejs/code-and-learn/issues/97 Refs: https://github.com/nodejs/node/issues/29766 Refs: https://github.com/nodejs/node/pull/29633 Reviewed-By: Colin Ihrig Reviewed-By: Michaƫl Zasso Reviewed-By: Yongsheng Zhang Reviewed-By: Gireesh Punathil --- lib/events.js | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/events.js b/lib/events.js index 1356806f6544c3..f3fa65153ce2be 100644 --- a/lib/events.js +++ b/lib/events.js @@ -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; @@ -65,7 +78,7 @@ function checkListener(listener) { } } -Object.defineProperty(EventEmitter, 'defaultMaxListeners', { +ObjectDefineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, get: function() { return defaultMaxListeners; @@ -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; } @@ -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++; @@ -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 }); @@ -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; @@ -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 @@ -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) @@ -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]; } @@ -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; } @@ -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) {