Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Array.splice() so slow?

I recently saw this benchmark: http://jsperf.com/remove-element-splice-vs-move-and-pop

I noticed that Array.splice() is several orders of magnitude slower than a for loop iterating through the elements. This lead me to wonder why Array.splice() is so slow.

Therefore, I came here to ask you: Why is Array.splice() so slow?

like image 727
Stack Tracer Avatar asked Jun 09 '15 23:06

Stack Tracer


People also ask

Is array splice fast?

Here's a good rule of thumb, based on tests done in Chrome, Safari and Firefox: Splicing a single value into the middle of an array is roughly half as fast as pushing/shifting a value to one end of the array.

What is the time complexity of array splice?

Discussion on: Removing an Element in an Array In-Place The problem with splice is, it has an O(n) time complexity in worst case.

Is it good to use splice ()?

The splice() method is mostly used when you need to delete or add new elements to an array. In some situations, you can also use it to separate an array which has mixed content as in the case above. When you remove 0 elements from the array, then the method will simply return an empty array.

What's the difference between array splice () and array slice () methods?

The slice( ) method copies a given part of an array and returns that copied part as a new array. It doesn't change the original array. The splice( ) method changes an array, by adding or removing elements from it. Note: the Slice( ) method can also be used for strings.


3 Answers

There is a fallacy in that benchmark: .splice preserves the order of the elements in the array, and therefore needs to move half of the elements until the hole created by the removal is sifted up to the end and can be removed by resizing the array. It follows that .splice works in linear time.

Conversely, this piece of code:

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

swaps the last element with the one to be removed, and shortens the array of 1 element, an operation that can be done in constant time. Technically, the snippet above does not even accomplish the declared goal, since it changes the order of elements in the array (!). Compare:

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

with:

> array[500000] = array[array.length-1];
> array.pop();
> console.log(array[500000])
999999
like image 77
Stefano Sanfilippo Avatar answered Oct 16 '22 21:10

Stefano Sanfilippo


splice will return your entire array, less the deleted item. So for the 1 element in the benchmark example, you have to copy the other 499999 elements to a new array. But pop just has to shorten the array by one element.

like image 24
Kim Ryan Avatar answered Oct 16 '22 20:10

Kim Ryan


Here are some measures from a real project (not a benchmark). I had a list of objects in an array and had to end up with a smaller subset. In the case shown here, the list happened to have 17,000 items and we happened to need just 7.

My first approach was to iterate through the array and use splice to remove those not needed. Firefox had major problems with that approach, taking over 12 seconds to do what Chrome did in 0.09 seconds! The second approach was to iterate in reverse, doing the same. The third was to copy the wanted objects to a new array.

              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

In the end, copying was much faster for all the browsers.

However, if you do need to splice, doing it in reverse may be much faster.

like image 1
Glen Little Avatar answered Oct 16 '22 22:10

Glen Little