-
-
Save bmeurer/576c6d397377a43876353c67c2eb50b0 to your computer and use it in GitHub Desktop.
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
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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.