是什么使代码更快

时间:2014-06-16 00:40:59

标签: javascript performance memoization

最初我测试了如何添加一些缓存结果的代码会影响初始计算时间。我创建了一个简单的递归函数来计算阶乘:

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

结果表明控件明显快于添加缓存的功能。因此得出以下结论:

  1. 数组f保持不变,操作/秒的差异是由初始计算引起的。

  2. 数组f正在重置&#34;每次由于某种原因它比正常版本更快。

  3. 我不相信初始计算会使整个测试比对照慢74%,因此#2应该是真的。但是什么使它比普通版本更快?从15,262,318 ops / sec到114,370,808 ops / sec,它实际上非常重要。

2 个答案:

答案 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;
  } 
}());

更多的是打字,但性能优势很明显。