为什么在这个基准测试中while(i–)循环比for循环慢?

想象一个非常简单的任务,它需要一个紧密的循环,比如对数组的值求和。我编写了 5 种不同的代码来实现这一点:

const arr = Array(1000000).fill(0).map(() => Math.random());

// 1: (ab)using .forEach
let x1 = 0;
arr.forEach((i) => x1 += i);

// 2. using reduce
let x2 = arr.reduce((a, n) => a + n, 0);

// 3: classic forward for-loop
let x3 = 0;
for(let i = 0; i < arr.length; i++)
    x3 += arr[i];

// 4: backward for-loop, should be faster, because comparison with a literal is faster
let x4 = 0;
for(let i = arr.length - 1; i >= 0; i--)
    x4 += arr[i];

// 5: backward while-loop, should be fastest, because it combines comparison and decrement
let x5 = 0;
let i = arr.length;

while(i--)
    x5 += arr[i];

我通常使用第一个或第二个版本,因为在大多数循环中,可读性比性能更重要。但是,为了好玩,我对此进行了基准测试。每次运行的结果略有不同,但在 Chrome 90.0.4430.95 上我看到了这个趋势:

  • 版本 1 和 2 是最慢的,差距很大(预期)
  • 版本 3、4 和 5 几乎同样快,但是
    • 5 几乎从来都不是最快的(令人惊讶!)
    • 大多数情况下,3 是最快的,与 4 相比略有差距(令人惊讶,但可能是由于测量不准确)

这是为什么?仅仅是基准不准确吗?那么为什么 5 几乎永远不会是最快的呢?我的浏览器是否优化了前向循环?

我想强调的是,这是一个纯粹的理论问题,在实际代码中,我并不关心这种微优化。

这里有一些我读过的参考问题:

JavaScript 循环性能 - 为什么将迭代器递减到 0 比递增更快- 从此我预计向后-for 比
向前-for 快。

Javascript 性能:While 与 For 循环- 从这里我预计 backward-while 比 backward-for 更快。

这两个问题都有些旧,因此由于更好的浏览器支持,它们可能已经过时了。

以上是为什么在这个基准测试中while(i–)循环比for循环慢?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>