我最近看到这个基准测试:http://jsperf.com/remove-element-splice-vs-move-and-pop
我注意到,Array.splice()的速度比通过循环遍历元素要慢几个数量级。这让我想知道为什么Array.splice()如此缓慢。
因此,我来问你:为什么Array.splice()如此缓慢?
因此,我来问你:为什么Array.splice()如此缓慢?
这个基准测试中存在一个谬误:.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
splice会返回删除所选项目后的整个数组。因此,在基准示例中的1个元素中,您需要将其他499999个元素复制到新数组中。但pop只需要将数组缩短一个元素。
splice
不会返回整个数组,也不会复制整个数组,请查看文档。 - Stefano Sanfilippo
splice
和pop
。 - Sampson