Why is this wrapped function call faster than a regular function?
This is indeed a very strange behaviour.
After some digging, I see that it's mentioned in a few past questions (for example, this one) that JS performs worse with recursion, such as in fib1
.
Now the question that rises is whether fib2
isn't a recursive function. I assume that because it creates a new anonymous function - rather than using the same memory reference to fib2
- it's practically "less recursive" and therefore performs better.
EDIT: After reading this question it looks like what's going on is some sort of Tail Call handling (fib2
uses tail recursion, as opposed to fib1
, where each call is calculated before the result can be returned).
Another interesting observation is that - to a certain degree - the recursion does work better, but then it's getting exponentially slower.
function fib1(n) {
if (n === 1) return 0;
if (n === 2) return 1;
return fib1(n - 1) + fib1(n - 2);
};
function fib2(n) {
return (() => {
if (n === 1) return 0;
if (n === 2) return 1;
return fib2(n - 1) + fib2(n - 2);
})();
};
function calculateAverageTime(func, iterations = 5) {
let sum = 0;
[...Array(iterations)].forEach(() => {
const start = new Date();
func();
const finish = new Date();
sum += (finish - start);
});
return Math.round(sum / iterations);
}
function compare(i) {
const fib1RunTime = calculateAverageTime(() => fib1(i));
const fib2RunTime = calculateAverageTime(() => fib2(i));
console.log(`Difference for fib(${i}) is ${(fib2RunTime - fib1RunTime)}ms`);
}
[10, 20, 30, 40].forEach(i => compare(i));