5

在阅读了最近关于优化的轰动一时的杂志文章后,我进行了一些测试,以了解从我的一个数组中间“删除”一个元素的最有效方法是什么。

在运行我自己的关于从数组中间拼接出一个值与删除它/将其设置为 null 的测试之后,我遇到了一个相当出乎意料的结果,即从数组中拼接出值使数组的遍历速度提高了一个数量级.

更多调查使我想到了这一点

出于某种原因,对数组中的第一条记录进行 .shift() 处理使其遍历速度提高了 300 倍(在 v8 中可以看到最大的性能,但它似乎对我尝试过的所有浏览器都有效)。

我怀疑我会滥用这个,因为我不认为实际的遍历是一个瓶颈,但是有谁知道为什么会发生这种行为?

编辑: jsPerf 的不正确使用是这里的根本问题,请参阅下面的答案。

4

3 回答 3

1

性能测试充满了无数错误。
最重要的一个是采样长度为 1000。使用今天的处理器,遍历 1000 项数组是立即完成的,并且您测量的第一个数组方法(移位、切片、...)所花费的时间比实际的数组遍历。
因此,您必须
1)使用更长的数组,
2)在循环之前执行切片/移位/...,因为这不是您想要测量的。

然后您将看到没有魔法,并且数组遍历对所有数组都花费相同的时间

我从http://jsperf.com/spliced-vs-non-spliced/4开始,适用于 normal/sliced(0,0) 和 shift() 情况。性能上的差异不如测量误差。

于 2012-11-21T16:36:51.407 回答
0

所以我尝试从每个函数中删除 for 循环,将核心数组函数与 for 循环本身进行比较。

http://jsperf.com/spliced-vs-non-spliced/3

由于每个函数内部工作的这些简单差异,基准是按数量级缩放的。通过简化到最小的部分,我们能够分离出真正的差异。基于此,我怀疑 for 循环实际上是更快或更慢地遍历 - 由于测试中的其他功能,它只是看起来如此。

尽管存在误解,但阐明 Array 函数的工作原理以及 JavaScript 开发人员应如何应用它们仍然非常有帮助。

于 2012-11-21T15:03:46.967 回答
0

好的,事实证明这实际上是我对 jsPerf 工作原理的误解。

脚本的设置部分是在每组循环开始时运行的,而不是每次尝试脚本时都运行它。

如此处所示数字实际上如您所料。

于 2012-11-21T16:10:11.053 回答