From 6e75b002c90a38f95b939ca1a2de6a685677e2b5 Mon Sep 17 00:00:00 2001 From: Anatoli Papirovski Date: Sun, 15 Oct 2017 00:44:47 -0400 Subject: [PATCH] events: use spread function param in emit With recent changes in V8, it is now as performant or faster to use spread parameter within EventEmitter.prototype.emit, especially in cases where looping over arguments is required. events/ee-emit.js n=2000000 4.40 % *** 1.505543e-06 events/ee-emit-1-arg.js n=2000000 2.16 % *** 2.434584e-10 events/ee-emit-2-args.js n=2000000 1.05 % ** 0.001764852 events/ee-emit-3-args.js n=2000000 2.18 % *** 3.234954e-08 events/ee-emit-6-args.js n=2000000 17.17 % *** 1.298702e-103 events/ee-emit-10-args.js n=2000000 17.14 % *** 1.144958e-97 This has a knock-on effect for modules that use events extensively, such as http2: http2/headers.js nheaders=0 n=1000 2.10 % *** 6.792106e-11 PR-URL: https://github.com/nodejs/node/pull/16212 Reviewed-By: Luigi Pinca Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell Reviewed-By: Refael Ackermann --- lib/extras/events.js | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/lib/extras/events.js b/lib/extras/events.js index b2bb8a45e9..ee87ecc87f 100644 --- a/lib/extras/events.js +++ b/lib/extras/events.js @@ -157,23 +157,22 @@ function emitMany(handler, isFn, self, args) { } } -EventEmitter.prototype.emit = function emit(type) { - var er, handler, len, args, i, events, domain; - var needDomainExit = false; - var doError = (type === 'error'); +EventEmitter.prototype.emit = function emit(type, ...args) { + let doError = (type === 'error'); - events = this._events; + const events = this._events; if (events !== undefined) doError = (doError && events.error === undefined); else if (!doError) return false; - domain = this.domain; + const domain = this.domain; // If there is no 'error' event listener then throw. if (doError) { - if (arguments.length > 1) - er = arguments[1]; + let er; + if (args.length > 0) + er = args[0]; if (domain !== null && domain !== undefined) { if (!er) { er = new Error('Unhandled "error" event'); @@ -198,37 +197,32 @@ EventEmitter.prototype.emit = function emit(type) { return false; } - handler = events[type]; + const handler = events[type]; if (handler === undefined) return false; + let needDomainExit = false; if (typeof process !== 'undefined' && domain && this !== process) { domain.enter(); needDomainExit = true; } - var isFn = typeof handler === 'function'; - len = arguments.length; - switch (len) { - // fast cases - case 1: + const isFn = typeof handler === 'function'; + switch (args.length) { + case 0: emitNone(handler, isFn, this); break; + case 1: + emitOne(handler, isFn, this, args[0]); + break; case 2: - emitOne(handler, isFn, this, arguments[1]); + emitTwo(handler, isFn, this, args[0], args[1]); break; case 3: - emitTwo(handler, isFn, this, arguments[1], arguments[2]); - break; - case 4: - emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + emitThree(handler, isFn, this, args[0], args[1], args[2]); break; - // slower default: - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; emitMany(handler, isFn, this, args); }