jsPerf.app is an online JavaScript performance benchmark test runner & jsperf.com mirror. It is a complete rewrite in homage to the once excellent jsperf.com now with hopefully a more modern & maintainable codebase.
jsperf.com URLs are mirrored at the same path, e.g:
https://jsperf.com/negative-modulo/2
Can be accessed at:
https://jsperf.app/negative-modulo/2
/**
* Parses the parameters of a function.toString() and returns them as an object
* @param {*} fn The function to get the parameters from
* @param {*} asArray If true, it returns an array instead of an object
* @returns An object (or array) with the parameters and their default values
* @author [bye-csavier](https://github.com/bye-csavier)
*/
function getFnArgs(fn, asArray = false){
if(!(typeof fn === 'function')) return null;
fn = fn.toString();
fn = fn.replace(/\s/gm, ''); //remove all white spaces
fn = fn.match(/(?<=\()(.+?)(?=\))/); //get the function arguments section
if(fn == null) return null; else fn = fn[0];
fn = fn.replace(/(\/\/.*$)|(\/\*[\s\S]*?\*\/)/g, '') //removes comments
fn = fn.replace(/(?<!\\)["']/g, '`') //simplifies string delimiters for less checks
let subStr = ''; let parsedArgs = "{"; let delimitersTest = {};
let openDelimiter = [];
const strToArg = (str) => {
parsedArgs += `'${str}':${str},`;
}
delimitersTest.open = "";
delimitersTest.close = "";
//recursive RegEx is not supported therefore this is the best I can do
fn.replace(/\{(.+?)\}|\[(.+?)\]|\((.+?)\)|`(.+?)`/g, (match, p1, p2, p3, p4) => {
if(p1){ delimitersTest.open += "{"; delimitersTest.close += "}"; }
else if(p2){ delimitersTest.open += "["; delimitersTest.close += "]"; }
else if(p3){ delimitersTest.open += "("; delimitersTest.close += ")"; }
else if(p4){ delimitersTest.open += "`"; delimitersTest.close += "`"; }
return match;
});
delimitersTest.isOpening = (char) => {
if(delimitersTest.open.indexOf(char) > -1){
openDelimiter.push(char);
}
}
delimitersTest.isClosing = (char) => {
let idx = delimitersTest.close.indexOf(char);
if(idx < 0) return;
if(delimitersTest.open.indexOf(openDelimiter[openDelimiter.length-1]) == idx){
openDelimiter.pop();
}
}
let argList = fn; //save a copy of the original argList for later evaluation
fn = (fn+',').split('') // string to array, and added trailing comma to push also the last argument
let len = fn.length, CAN_READ = true;
for(let i=0; i<len; i++){
if(fn[i] == '=') CAN_READ = false;
else if(openDelimiter.length > 0){
if(openDelimiter.length > 0) delimitersTest.isClosing(fn[i])
}
else if(openDelimiter.length == 0 && (fn[i] == ',')){
strToArg(subStr);
subStr = '';
CAN_READ = true;
}
else{
if(delimitersTest.isOpening(fn[i])) CAN_READ = false;
if(CAN_READ) subStr += fn[i];
}
}
parsedArgs += '}';
fn = `((${argList})=>{return ${parsedArgs}})();`;
parsedArgs = eval(fn);
if(!asArray) return parsedArgs;
return Object.values(parsedArgs);
}
function test(a,
b=2, c={a:2, b:'lol'}, dee, e=[2,3,"a"],/*lol joke=2,2*/ foook=e, g=`test, ok`, h={a:'ok \"', b:{c:'lol=2,tricky=2', d:'lol'}}, i=[2,5,['x']] //ajaim
) {
return {
a: a,
b: b,
c: c,
dee: dee,
e: e,
foook: foook,
g: g,
h: h,
i: i
}
}
Ready to run.
Test | Ops/sec | |
---|---|---|
parsing function arguments |
| ready |
- |
| ready |
You can edit these tests or add more tests to this page by appending /edit to the URL.