最初我测试了如何添加一些缓存结果的代码会影响初始计算时间。我创建了一个简单的递归函数来计算阶乘:
function fac(n){
return n <= 1 ? 1 : fac(n-1) * n;
}
然后我添加缓存结果的部分供以后使用:
var f = [];
function fac(n){
return n <= 1 ? 1 : f[n] ? f[n] : f[n] = fac(n-1) * n;
}
I put them in jsPerf结果是带缓存的版本意外地更快。我怀疑这可能是因为我使用的数组f
在测试运行器中保持不变。该函数只是从数组中获取值,因此速度更快。
测试我创建了另一个只返回数组值的函数:
var test = []; test[10] = 3628800;
function control(n){
return n <= 1 ? 1 : test[n] ? test[n] : 1;
}
结果表明控件明显快于添加缓存的功能。因此得出以下结论:
数组f
保持不变,操作/秒的差异是由初始计算引起的。
数组f
正在重置&#34;每次由于某种原因它比正常版本更快。
我不相信初始计算会使整个测试比对照慢74%,因此#2应该是真的。但是什么使它比普通版本更快?从15,262,318 ops / sec到114,370,808 ops / sec,它实际上非常重要。
答案 0 :(得分:0)
我怀疑control
如此优化的原因是因为它没有用。快速浏览一下,它只有2个可能的返回值:test[10]
或1
。由于你从未在函数中向test
添加任何内容,因此它可能会被优化到几乎没有。
答案 1 :(得分:0)
小心性能测试,通常在一个主机中更快的速度在另一个主机中更慢。
如果您真的关心速度,请不要使用递归,因为顺序循环在所有主机中几乎总是快得多。阶乘函数通常用于递归示例,因为它易于理解并与非递归函数进行比较,而不是因为它更快。
使用存储结果的循环函数应该是最快的:
var factorial = (function () {
var facStore = [1,1,2];
return function (n) {
var x = n;
var result = 1;
if (n == 0 || facStore[n]) return facStore[n];
while (n) result = result * n--;
facStore[x] = result;
return result;
}
}());
更多的是打字,但性能优势很明显。