我从一些非特定来源听说,使用shift()
和的组合pop()
比使用splice()
. 我还没有运行基准测试,并且很可能不会因为我不在城里而有一段时间,但这是真的吗?如果是这样,为什么?
3 回答
如果您不需要保留 Array 的顺序,则 using.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
我尝试了另一个代码,结果如下所示:
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 的回答,但是如果您从一个索引中删除所有最后的数据,而不是仅删除孔位置,我会建议拼接而不是弹出。
经典算法有时更快。不更改数组大小是实现非常快速性能的另一种方法。在使用 performance.now() 进行了几次测试后,我发现在下面的案例中,这个经典算法比任何改变数组大小的方法都快,并且像所有 javascript 代码一样,使用本地变量变得更快。
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 个索引),您绝对应该考虑经典算法。