3

I've heard from some nonspecific sources that using a combination of shift() and pop() is faster than using splice(). I haven't run a benchmark test yet and will most likely not for a while since I'm out of town, but is this true, and if so, why?

Ricardo Souza
  • 16,030
  • 6
  • 37
  • 69
David
  • 877
  • 1
  • 7
  • 18

3 Answers3

12

If you don't need to retain the order of your Array, using .pop() is much, much faster than .splice().

.splice() will remove an element at a given index. What happens then is that every other element in the array after that one will need to have its position in the array reduced by 1. This can be slow if your array is large and the index at which you remove an element is small.

Using .pop(), you can remove this process of re-indexing everything entirely. Instead of removing an element at a given index, you can use .pop() to remove the last item from the array. From here, all you need to do is replace the item you want to remove with the one you got from using .pop(). As mentioned, this will of course mean that the order of your elements is not maintained.

Code examples:

.splice():

var list:Array = [0,1,2,3,4,5];
list.splice(2, 1);

trace(list); // 0,1,3,4,5

And then .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.

And here we have the all-important actual performance tests:

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));
}

The results:

emptyViaSplice(); // 12153 ms
emptyViaPop(); // 37 ms
Marty
  • 39,033
  • 19
  • 93
  • 162
0

I tried another code and the result shows below:

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();

The results:

halfViaSplice: 0
halfViaPop: 4

I agree with Marty's answer, but if you remove all the last data from one index but not just remove in a hole position, I would advice splice than pop.

Nfer.zhuang
  • 11
  • 1
  • 5
0

Classic algorithms sometimes are faster. Making no changes on the Array size is another way to achieve a very fast performance. After several tests made with performance.now(), I found out the in the case below, this classic algorithm is faster than any method that changes array sizes and, like all javascript codes, gets faster with local vars.

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]];

Compared in equal circumstances, the code above, has proven to be slightly faster than

Array.shift(); Array.push([[newdata1],[ newdata2]]);

For small arrays (20 to 60 indexes) that are cyclically changed, you should definitely consider classic algorithms.

Avinash Dalvi
  • 8,551
  • 7
  • 27
  • 53
Abel
  • 1
  • 2