为什么Array.splice()这么慢?

时间:2015-06-09 23:07:28

标签: javascript arrays performance time

我最近看到了这个基准:http://jsperf.com/remove-element-splice-vs-move-and-pop

我注意到Array.splice()比迭代遍历元素的for循环要慢几个数量级。这让我想知道为什么Array.splice()太慢了。

因此,我来​​到这里问你:为什么Array.splice()这么慢?

3 个答案:

答案 0 :(得分:5)

该基准测试中存在一个谬误:.splice保留了数组中元素的顺序,因此需要移动一半元素,直到删除创建的洞被筛选到最后并且可以通过调整数组大小来删除。因此.splice可以在线性时间中工作。

相反,这段代码:

array[500000] = array[array.length-1];
array.pop();

将最后一个元素与要删除的元素交换,并缩短1个元素的数组,这个操作可以在恒定时间中完成。从技术上讲,上面的代码段甚至没有完成声明的目标,因为它改变了数组中元素的顺序(!)。比较:

> array.splice(500000,1)
> console.log(array[500000])
500001

使用:

> array[500000] = array[array.length-1];
> array.pop();
> console.log(array[500000])
999999

答案 1 :(得分:3)

splice将返回整个数组,减去已删除的项目。因此,对于基准测试示例中的1元素,您必须将其他499999个元素复制到新数组中。但是pop必须缩短数组  一个元素。

答案 2 :(得分:1)

以下是来自真实项目(不是基准)的一些衡量标准。我有一个数组中的对象列表,最后得到一个较小的子集。在这里显示的情况下,列表恰好有17,000个项目,我们碰巧只需要7个。

我的第一种方法是遍历数组并使用splice删除不需要的数组。 Firefox在这方面遇到了很大的问题,花了12秒多的时间来完成Chrome在0.09秒内所做的事情!第二种方法是反向迭代,做同样的事情。第三个是将所需对象复制到一个新数组。

              Splice Forward   Splice Reverse   Copy to Array   (time in milliseconds)
Chrome 51             91              64             47
IE 11.0.31           309             144             31
Firefox 47        12,544              61             21

最后,所有浏览器的复制速度都要快得多。

但是,如果确实需要splice,反向执行可能要快得多。