Last active
October 8, 2017 09:30
-
-
Save bmeurer/9a9ddae717e9085a31c4e27d9720b2bc to your computer and use it in GitHub Desktop.
Isolated test case for the discussion around rest parameters for Node's EventEmitter (https://github.com/nodejs/node/pull/13155#issuecomment-334706721)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Isolated test case for the discussion around rest parameters for Node's EventEmitter | |
// https://github.com/nodejs/node/pull/13155#issuecomment-334706721 | |
if (typeof console === 'undefined') console = {log:print}; | |
const N = 2e7; | |
const TESTS = []; | |
(function() { | |
function emitNone(handler, isFn, self) { | |
if (isFn) | |
handler.call(self); | |
else { | |
var len = handler.length; | |
var listeners = arrayClone(handler, len); | |
for (var i = 0; i < len; ++i) | |
listeners[i].call(self); | |
} | |
} | |
function emitOne(handler, isFn, self, arg1) { | |
if (isFn) | |
handler.call(self, arg1); | |
else { | |
var len = handler.length; | |
var listeners = arrayClone(handler, len); | |
for (var i = 0; i < len; ++i) | |
listeners[i].call(self, arg1); | |
} | |
} | |
function emitTwo(handler, isFn, self, arg1, arg2) { | |
if (isFn) | |
handler.call(self, arg1, arg2); | |
else { | |
var len = handler.length; | |
var listeners = arrayClone(handler, len); | |
for (var i = 0; i < len; ++i) | |
listeners[i].call(self, arg1, arg2); | |
} | |
} | |
function emitThree(handler, isFn, self, arg1, arg2, arg3) { | |
if (isFn) | |
handler.call(self, arg1, arg2, arg3); | |
else { | |
var len = handler.length; | |
var listeners = arrayClone(handler, len); | |
for (var i = 0; i < len; ++i) | |
listeners[i].call(self, arg1, arg2, arg3); | |
} | |
} | |
function emitMany(handler, isFn, self, args) { | |
if (isFn) | |
handler.apply(self, args); | |
else { | |
var len = handler.length; | |
var listeners = arrayClone(handler, len); | |
for (var i = 0; i < len; ++i) | |
listeners[i].apply(self, args); | |
} | |
} | |
const EventEmitter = class EventEmitter { | |
constructor() { this._events = Object.create(null); } | |
emit(type) { | |
const events = this._events; | |
const handler = events[type]; | |
if (!handler) return false; | |
var isFn = typeof handler === 'function'; | |
var len = arguments.length; | |
switch (len) { | |
// fast cases | |
case 1: | |
emitNone(handler, isFn, this); | |
break; | |
case 2: | |
emitOne(handler, isFn, this, arguments[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]); | |
break; | |
// slower | |
default: | |
args = new Array(len - 1); | |
for (i = 1; i < len; i++) | |
args[i - 1] = arguments[i]; | |
emitMany(handler, isFn, this, args); | |
} | |
return true; | |
} | |
on(type, handler) { | |
this._events[type] = handler; | |
} | |
}; | |
const ee = new EventEmitter(); | |
for (var k = 0; k < 10; k += 1) | |
ee.on('dummy', function() {}); | |
TESTS.push( | |
function testDispatchNode() { | |
ee.emit('dummy'); | |
}, | |
function testDispatchNodeMultiArgs() { | |
ee.emit('dummy', 5, true); | |
}); | |
})(); | |
(function() { | |
const EventEmitter = class EventEmitter { | |
constructor() { this._events = Object.create(null); } | |
emit(type, ...args) { | |
const events = this._events; | |
const handler = events[type]; | |
if (typeof handler === 'function') { | |
handler.call(this, ...args); | |
} else if (handler != null) { | |
var len = handler.length; | |
var listeners = arrayClone(handler, len); | |
for (var i = 0; i < len; ++i) | |
listeners[i].call(this, ...args); | |
} | |
return true; | |
} | |
on(type, handler) { | |
this._events[type] = handler; | |
} | |
}; | |
const ee = new EventEmitter(); | |
for (var k = 0; k < 10; k += 1) | |
ee.on('dummy', function() {}); | |
TESTS.push( | |
function testDispatchRest() { | |
ee.emit('dummy'); | |
}, | |
function testDispatchRestMultiArgs() { | |
ee.emit('dummy', 5, true); | |
}); | |
})(); | |
function test(fn) { | |
var result; | |
for (var i = 0; i < N; i += 1) result = fn(); | |
return result; | |
} | |
for (var j = 0; j < TESTS.length; ++j) { | |
test(TESTS[j]); | |
} | |
for (var j = 0; j < TESTS.length; ++j) { | |
var startTime = Date.now(); | |
test(TESTS[j]); | |
console.log(TESTS[j].name + ':', (Date.now() - startTime), 'ms.'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Results with V8 6.1 and 6.2: