使用数组时 Javascript 向后循环速度较慢?

Javascript backwards loop slower when working with arrays?

提问人:Katai 提问时间:8/8/2015 最后编辑:p uKatai 更新时间:1/29/2019 访问量:351

问:

我们中的许多人可能已经知道这一点:

var list = ...
var index = list.length

while( index-- ) {
    // do something
}

据说这是在 javascript 中进行循环的最快方法,因为您可以避免额外的测试。到目前为止,在过去的几年里,我在处理速度很重要且顺序并不重要的数据时使用了这种技术。

但是现在我偶然发现了一篇文章,说这在处理数组时实际上更慢

这使您避免了额外的测试(与标准相比 循环)。但你知道吗?这将比使用 正确的顺序。因为世界上所有的 CPU 缓存都期望处理 为了“直截了当”,您将一次又一次地出现缓存未命中,以及 2 倍 当你幸运的时候,放慢速度是你会得到的。

所以不要向后循环,除非你有很好的理由这样做。

来源:https://gamealchemist.wordpress.com/2013/05/01/lets-get-those-javascript-arrays-to-work-fast/

现在我很好奇!我只有有限的可能性来测试这些东西,我发现的每个其他地方仍然说向后循环是最快的方法(甚至在stackoverflow上有多个答案)。在处理(可能是大型)数组时,真的是这样吗?

在过早的优化答案出现之前(就像这种类型的问题经常做的那样):这主要只是好奇心,是的,在游戏之类的事情上,性能很重要!

关于 jsperf:到目前为止,jsperf 似乎暗示向后循环更快(我现在无法检查测试,因为它不会在任何 atm 上加载结果 - 所以我回想起我之前看到的内容)。这就是这个问题的来源:这两条信息是自相矛盾的——至少如果那篇文章中所说的是真的!那么,到底什么是“正确的”呢?

JavaScript 数组 性能 while 循环

评论

3赞 jfriend00 8/8/2015
你为什么不在你关心的浏览器中用jsperf测试它(需要几分钟才能得到你的第一个结果)?所有性能问题都必须在您关心的环境中通过测试来回答。在没有自己测试的情况下发布这个问题似乎表明您只是想让其他人为您进行测试。
0赞 Sushant 8/8/2015
好吧,与事实相关的缓存错过是真的。CPU 期望按顺序遍历数组。
0赞 jfriend00 8/8/2015
此外,由于 JS 引擎会定期添加性能增强,因此完全有可能一些或许多浏览器为典型的数组迭代循环添加了优化以加快速度。你几年前读到的东西,今天可能仍然不适用。for
0赞 Katai 8/8/2015
@jfriend00 是的,但这也是问题所在(也是这个问题的原因):jsperf 似乎暗示向后循环更快(这些年来我在这里看到过一些测试)。所以 jsperf 实际上与此相矛盾 - 但也许情况也是如此,因为这些测试过于专注于一件事?我真的很想听听“因为世界上所有的 CPU 缓存都希望处理是'直接'的,所以你会有缓存未命中......”的论点。是以现实为基础的——因为如果是这样的话,理论上向后循环应该更慢,对吧?
1赞 jfriend00 8/8/2015
如果您在多个浏览器中拥有当前的 jsperf 性能数据,请发布它。如果没有一些性能数据,这个问题真的毫无意义。在进行测量以了解当前事态之前,没有任何有用的讨论。你不能通过对事物进行理论化来弄清楚哪件事会更快。你测量。您可以尝试通过理论化来解释测量,但不能反过来。

答:

0赞 Jon Hanna 1/29/2019 #1

该论点的推理是无效的。CPU 缓存在有序内存访问方面提供了好处,因为它们缓存了内存块,如果您按顺序浏览内存,那么您将连续几次命中同一个块,而不必每次都加载一个块。

但是,无论您是在这样的线性进程中前进还是后退,这与这是否适用没有区别。

可能有许多不同的因素在起作用,影响这些替代方案的相对性能(尤其是如果引擎试图优化特定的常见模式,这可能意味着那些看起来比竞争对手做更多工作的人实际上做得更少)。这些因素也可能因平台而异。

但是,期望向前访问击败向后访问的特殊原因并没有成功。

评论

0赞 Bergi 1/29/2019
它似乎指的是缓存预取,它试图在缓存未命中之前获取下一个缓存块。
0赞 Jon Hanna 1/29/2019
@Bergi,当我不尝试更异国情调的东西时,我以为这是双向的。毕竟,增加和减少用于堆栈的内存是一种特别常见的模式。
0赞 Bergi 1/29/2019
是的,你需要有一个非常愚蠢的预测器,我只是想提一下,这个推理并不是完全无效的。然而,我完全同意“可能有很多不同的因素在起作用......"