我从一些非特定来源获悉,使用shift()
和pop()
的组合比使用splice()
更快。我还没有进行基准测试,并且很可能暂时没有,因为我不在城里,但这是真的,如果是的话,为什么?
答案 0 :(得分:6)
如果您不需要保留数组的顺序,则使用.pop()
要比.splice()
快得多。
.splice()
将删除给定索引处的元素。然后会发生的是,数组之后的数组中的每个其他元素都需要将其在数组中的位置减少1.如果数组很大并且删除元素的索引很小,这可能会很慢。
使用.pop()
,您可以删除完全重新索引所有内容的过程。您可以使用.pop()
从数组中删除最后一项,而不是删除给定索引处的元素。从这里开始,您需要做的就是使用.pop()
替换要删除的项目。如上所述,这当然意味着不保持元素的顺序。
代码示例:
.splice()
:
var list:Array = [0,1,2,3,4,5];
list.splice(2, 1);
trace(list); // 0,1,3,4,5
然后.pop()
:
var last:* = list.pop();
list[2] = last;
trace(list); // 0,1,5,4 - Notice we move 5 to the index 2 and lose the order.
在这里,我们进行了非常重要的实际性能测试:
var list:Array = [];
function fillList():void
{
for(var i = 0; i < 200000; i++) list.push(i);
}
function emptyViaSplice():void
{
fillList();
var t:Number = getTimer();
while(list.length > 0)
{
list.splice(0, 1);
}
trace("emptyViaSplice: " + (getTimer() - t));
}
function emptyViaPop():void
{
fillList();
var t:Number = getTimer();
while(list.length > 0)
{
if(list.length == 1) list.pop();
else
{
var l:* = list.pop();
list[0] = l;
}
}
trace("emptyViaPop: " + (getTimer() - t));
}
结果:
emptyViaSplice(); // 12153 ms
emptyViaPop(); // 37 ms
答案 1 :(得分:0)
我尝试了其他代码,结果如下所示:
var length = 200000;
function fillList() {
var list = [];
for(var i = 0; i < length; i++)
list.push(i);
return list;
}
function halfViaSplice() {
var list = fillList();
var startTime = new Date();
list.splice(length/2, length/2);
var endTime = new Date();
console.log("halfViaSplice: " + (endTime - startTime));
}
function halfViaPop() {
var list = fillList();
var startTime = new Date();
while(list.length > length/2) {
list.pop();
}
var endTime = new Date();
console.log("halfViaPop: " + (endTime - startTime));
}
halfViaSplice();
halfViaPop();
结果:
halfViaSplice: 0
halfViaPop: 4
我同意Marty的答案,但是如果你从一个索引中删除所有最后的数据但不只是删除一个孔位置,我会建议拼接而不是pop。
答案 2 :(得分:0)
经典算法有时会更快。不更改数组大小是获得非常快的性能的另一种方法。 经过对performance.now()的几次测试,我发现在下面的情况下,这种经典算法比任何更改数组大小的方法都要快,并且像所有JavaScript代码一样,使用本地var可以更快。
var ArrayLength = Array.length; // always prefer the simplest references.
for (i=1; i < ArrayLength; i++) {Array[(i-1)] = Array[i];}
Array [ArrayLength-1] = [[newdata1],[newdata2]];
在相同情况下,以上代码已被证明比
Array.shift(); Array.push([[newdata1],[ newdata2]]);
对于周期性变化的小型数组(20至60个索引),您绝对应该考虑经典算法。