gpt4 book ai didi

javascript - 为什么这个包装函数调用比普通函数更快?

转载 作者:行者123 更新时间:2023-12-03 06:50:23 24 4
gpt4 key购买 nike

在我的机器上执行这个递归斐波那契函数大约需要 9.5 秒,使用传统方法:

const fib = n => {
if (n == 1) return 0;
if (n == 2) return 1;
return fib(n - 1) + fib(n - 2);
};

console.log(fib(45));
➜ time node index.js
701408733
node index.js 9,50s user 0,04s system 99% cpu 9,566 total
但是,当我将函数体包装在另一个立即执行的函数中时,执行时间会下降到 7.5 秒:
const fib = n => {
return (() => {
if (n == 1) return 0;
if (n == 2) return 1;
return fib(n - 1) + fib(n - 2);
})();
};

console.log(fib(45));
➜ time node index.js
701408733
node index.js 7,58s user 0,25s system 99% cpu 7,852 total
这是一个巨大的加速(〜30%!),但我无法弄清楚为什么包装函数会产生这种差异。

最佳答案

这确实是一种非常奇怪的行为。
经过一番挖掘,我发现在过去的几个问题(例如 this one )中提到 JS 在递归方面表现更差,例如在 fib1 中.
现在提出的问题是fib2不是递归函数。我假设这是因为它创建了一个新的匿名函数 - 而不是使用对 fib2 的相同内存引用- 它实际上是“更少递归”,因此性能更好。
编辑 : 看完this question看起来正在发生的事情是某种尾调用处理( fib2 使用尾递归,而不是 fib1 ,在返回结果之前计算每个调用)。
另一个有趣的观察是 - 在一定程度上 - 递归确实工作得更好,但它会以指数方式变慢。

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));

关于javascript - 为什么这个包装函数调用比普通函数更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64479734/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com