Skip to content

Instantly share code, notes, and snippets.

@bmeurer
Created August 13, 2017 07:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bmeurer/576c6d397377a43876353c67c2eb50b0 to your computer and use it in GitHub Desktop.
Save bmeurer/576c6d397377a43876353c67c2eb50b0 to your computer and use it in GitHub Desktop.
function applyFunctionsRest(functions, ...args) {
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].apply(this, args);
}
}
function applyFunctionsRestSpread(functions, ...args) {
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].call(this, ...args);
}
}
function applyFunctionsSlice(functions) {
"use strict";
var args = Array.prototype.slice.call(arguments, 1);
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].apply(this, args);
}
}
function applyFunctionsSwitch(functions, param1, param2) {
"use strict";
for (var i = 0, l = functions.length; i < l; ++i) {
switch (arguments.length) {
case 1:
functions[i].call(this);
case 2:
functions[i].call(this, param1);
break;
case 3:
functions[i].call(this, param1, param2);
break;
default:
functions[i].apply(this, Array.prototype.slice.call(arguments, 1));
break;
}
}
}
function applyFunctionsSwitchOptimized(functions, param1, param2) {
"use strict";
switch (arguments.length) {
case 1:
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].call(this);
}
case 2:
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].call(this, param1);
}
break;
case 3:
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].call(this, param1, param2);
}
break;
default: {
var args = new Array(arguments.length - 1);
for (var i = 0; i < arguments.length - 1; ++i) {
args[i] = arguments[i + 1];
}
for (var i = 0, l = functions.length; i < l; ++i) {
functions[i].apply(this, args);
}
break;
}
}
}
const applyFunctions = [
applyFunctionsRest,
applyFunctionsRestSpread,
applyFunctionsSlice,
applyFunctionsSwitch,
applyFunctionsSwitchOptimized
];
const n = 1e6;
function test(applyFun) {
const fns = [x => x, (x, y) => y, (x, y, z) => z, (x, y, z, w) => w];
for (var i = 0; i < n; ++i) {
applyFun(fns);
applyFun(fns, i);
applyFun(fns, i, i);
applyFun(fns, i, i, i);
}
}
// Warmup
for (const applyFun of applyFunctions) {
test(applyFun);
}
// Measure
for (const applyFun of applyFunctions) {
console.time(applyFun.name);
test(applyFun);
console.timeEnd(applyFun.name);
}
@robpalme
Copy link

applyFunctionsSwitch & applyFunctionsSwitchOptimized have a bug: they miss a "break" so do extra work.
It doesn't make any difference to the conclusion.
applyFunctionsRest still wins by >20% on v8 master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment