【发布时间】:2015-10-31 16:25:53
【问题描述】:
我们中的许多人可能已经知道这一点:
var list = ...
var index = list.length
while( index-- ) {
// do something
}
据说这是在 javascript 中执行循环的最快方法,因为您避免了额外的测试。到目前为止,在过去的几年中,我在处理速度很重要但顺序并不重要的数据时使用了这种技术。
但现在我偶然发现一篇文章说处理数组时实际上速度较慢。
这使您避免了额外的测试(与标准相比 环形)。但你知道吗?这将比使用 正确的顺序。因为世界上所有的 CPU 缓存都期望处理 要“直接”,您将一次又一次地缓存未命中,并且 2X 当你幸运的时候,你会慢下来。
所以不要向后循环,除非你有充分的理由这样做。
来源:https://gamealchemist.wordpress.com/2013/05/01/lets-get-those-javascript-arrays-to-work-fast/
现在我很好奇!我只有有限的可能性来测试这些东西,而且我发现的所有其他地方仍然说反向循环是最快的方法(甚至是 stackoverflow 上的多个答案)。 在处理(可能很大)数组时真的是这样吗?
在过早的优化答案弹出之前(就像这类问题经常发生的那样):这主要是出于好奇,是的,在游戏之类的事情中,性能很重要!
关于 jsperf: 到目前为止,jsperf 似乎暗示向后循环更快(我现在无法检查测试,因为它不会在任何 atm 上加载结果 - 所以我我在回忆我之前看到的)。这就是这个问题的来源:这两条信息相互矛盾——至少如果那篇文章中所说的是真的!那么到底什么是“正确”呢?
【问题讨论】:
-
你为什么不在你关心的浏览器中用 jsperf 测试它(需要几分钟才能得到你的第一个结果)?所有性能问题都必须通过在您关心的环境中进行测试来回答。发布此问题而您自己没有进行任何测试似乎表明您只是希望其他人为您进行测试。
-
与缓存未命中相关的事实是正确的。 CPU 期望数组按顺序遍历。
-
另外,由于 JS 引擎会定期添加性能增强功能,因此完全有可能某些或许多浏览器已经为典型的数组迭代
for循环添加了优化以加快速度。你几年前读过的东西,今天可能不再适用。 -
@jfriend00 是的,但这也是问题所在(也是这个问题的原因):jsperf 似乎暗示向后循环更快(这些年来我在这里看到了一些测试)。所以 jsperf 实际上与此相矛盾 - 但也许情况也是如此,因为这些测试过于专注于一件事?我真的很想知道“因为世界上所有的 CPU 缓存都希望处理是‘直接的’,所以你会有缓存未命中……”这个论点是否基于现实——因为如果是这样的话,反向循环理论上应该慢一点,对吧?
-
如果你在几个浏览器中有当前的 jsperf 性能数据,那就贴出来吧。如果没有一些性能数据,这个问题真的毫无意义。在进行测量以了解当前的事态之前,没有什么有用的讨论。通过对事物进行理论化,您无法弄清楚哪件事会更快。你测量。您可以尝试通过理论化来解释测量,但不能反过来。
标签: javascript arrays performance loops while-loop