【问题标题】:Array traversal magnitudes faster after removing the first element删除第一个元素后数组遍历幅度更快
【发布时间】:2012-11-09 19:16:42
【问题描述】:

在阅读了the recent smashing magazine 关于优化的文章后,我进行了一些测试,看看什么是从我的一个数组中间“删除”一个元素的最有效方法。

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

更多调查将我带到this

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

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

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

【问题讨论】:

    标签: javascript arrays optimization traversal


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

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

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

      【讨论】:

      • 我不这么认为,如果是这样的话,那么这个测试用例jsperf.com/spliced-vs-non-spliced/6 应该会得出它们两者的速度大致相同,拼接的速度非常非常快,这不会似乎不是这样。
      【解决方案3】:

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

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

      here 所示,数字实际上如您所料。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-23
        • 2012-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-06
        相关资源
        最近更新 更多