What's the time complexity of array.splice() in Google Chrome?

后端 未结 2 1764
执笔经年
执笔经年 2020-12-01 10:43

If I remove one element from an array using splice() like so:

arr.splice(i, 1);

Will this be O(n) in the worst case because it

相关标签:
2条回答
  • 2020-12-01 10:58
    The Test:

    I took the advice in the comments and wrote a simple test to time splicing a data-set array of size 3,000, each one containing 3,000 items in it. The test would simply splice the

    • first item in the first array
    • second item in the second array
    • third item in the third array
    • ...
    • 3000th item in the 3000th array

    I pre-built the array to keep things simple.

    The Findings:

    The weirdest thing is that the number of times where the process of the splice even takes longer than 1ms grows linearly as you increase the size of the dataset.

    I went as far as testing it for a dataset of 300,000 on my machine (but the SO snippet tends to crash after 3,000).

    I also noticed that the number of splice()s that took longer than 1ms for a given dataset (30,000 in my case) was random. So I ran the test 1,000 times and plotted the number of results, and it looked like a standard distribution; leading me to believe that the randomness was just caused by the scheduler interrupts.

    This goes against my hypothesis and @Ivan's guess that splice()ing from the beginning of an array will have a O(n) time complexity

    Below is my test:

    let data = []
    const results = []
    const dataSet = 3000
    
    function spliceIt(i) {
      data[i].splice(i, 1)
    }
    
    function test() {
      for (let i=0; i < dataSet; i++) {
        let start = Date.now()
        spliceIt(i); 
        let end = Date.now()
        results.push(end - start)
      }
    }
    
    function setup() {
      data = (new Array(dataSet)).fill().map(arr => new Array(dataSet).fill().map(el => 0))
    }
    
    setup()
    test()
    // console.log("data before test", data)
    // console.log("data after test", data)
    // console.log("all results: ", results)
    console.log("results that took more than 1ms: ", results.filter(r => r >= 1))

    0 讨论(0)
  • 2020-12-01 11:10

    Worst case should be O(n) (copying all n-1 elements to new array).

    A linked list would be O(1) for a single deletion.

    For those interested I've made this lazily-crafted benchmark. (Please don't run on Windows XP/Vista). As you can see from this though, it looks fairly constant (i.e. O(1)), so who knows what they're doing behind the scenes to make this crazy-fast. Note that regardless, the actual splice is VERY fast.

    Rerunning an extended benchmark directly in the V8 shell that suggest O(n). Note though that you need huge array sizes to get a runtime that's likely to affect your code. This should be expected as if you look at the V8 code it uses memmove to create the new array.

    0 讨论(0)
提交回复
热议问题