Skip to content
This repository has been archived by the owner on Aug 31, 2018. It is now read-only.

Commit

Permalink
events: use spread function param in emit
Browse files Browse the repository at this point in the history
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: nodejs/node#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 authored and addaleax committed Dec 7, 2017
1 parent 11b23c8 commit 6e75b00
Showing 1 changed file with 17 additions and 23 deletions.
40 changes: 17 additions & 23 deletions lib/extras/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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);
}

Expand Down

0 comments on commit 6e75b00

Please sign in to comment.