为什么流行音乐比移动快?

zjm*_*ler 29 javascript performance

JavaScript中的道格拉斯·克罗克福德(Douglas Crockford)表示"转变通常比流行音乐慢得多".jsPerf 证实了这一点.有谁知道为什么会这样?从一个不成熟的角度来看,他们似乎做了几乎相同的事情.

gee*_*aur 34

要删除返回的项而不重新寻址数组并使对它的所有引用无效,shift()需要移动整个数组; pop()可以简单地从长度中减去1.

  • 附录:据我所知,目前没有任何JavaScript实现像Perl那样做,保持一个起始偏移量,以便`shift`可以简单地增加它.但它*可以*,这将消除这种放缓. (12认同)
  • 使用起始索引意味着需要额外的工作来获取每个索引,因为你必须使用*startIndex + index*来获得你想要的那个.我怀疑如果转换操作真的很受欢迎,可以实现startIndex或类似操作,但由于直接属性访问更受欢迎,因此更好地进行优化. (3认同)

And*_*ore 23

shift()必须重新索引整个数组,而pop()不是.

pop()只需删除数组中的最后一个元素.因此,元素不动; 只.length需要更新.

shift()删除数组中的第一个元素.这需要重新索引数组中的所有元素,以便[1]成为[0]等等.


小智 10

我正在对节点(使用chrome v8)进行一些测试,并注意到对于大约120k元素的阵列,shift的性能非常接近pop.一旦你超过120K,它似乎会大幅放缓.

var sum;
var tests = [125000,130000];

console.log(JSON.stringify(process.versions));

tests.forEach(function(count) {
    console.log('Testing arrays of size ' + count);
    var s1 = Date.now();
    var sArray = new Array(count);
    var pArray = new Array(count);
    for (var i = 0; i < count ; i++) {
      var num = Math.floor(Math.random() * 6) + 1
      sArray[i] = num;
      pArray[i] = num;
    }
    console.log(' -> ' + (Date.now() - s1) + 'ms: built arrays with ' + count + ' random elements');

    s1 = Date.now();
    sum = 0;
    while (pArray.length) {
      sum += pArray.pop();
    }
    console.log(' -> ' + (Date.now() - s1) + 'ms: sum with pop() ' + count + ' elements, sum = ' + sum);

    s1 = Date.now();
    sum = 0;
    while (sArray.length) {
      sum += sArray.shift();
    }
    console.log(' -> ' + (Date.now() - s1) + 'ms: sum with shift() ' + count + ' elements, sum = ' + sum);
});
Run Code Online (Sandbox Code Playgroud)

输出:

{"http_parser":"1.0","node":"0.10.22","v8":"3.14.5.9","ares":"1.9.0-DEV","uv":"0.10.19","zlib":"1.2.3","modules":"11","openssl":"1.0.1e"} 
Testing arrays of size 125000
-> 14ms: built arrays with 125000 random elements
-> 2ms: sum with pop() 125000 elements, sum = 436673
-> 6ms: sum with shift() 125000 elements, sum = 436673 
Testing arrays of size 130000
-> 50ms: built arrays with 130000 random elements
-> 1ms: sum with pop() 130000 elements, sum = 455971
-> 54372ms: sum with shift() 130000 elements, sum = 455971
Run Code Online (Sandbox Code Playgroud)

  • 我在 chrome 中没有看到。即使对于小数组,shift 似乎也比 pop 慢得多:http://jsperf.com/push-pop-vs-unshift-shift/3 (3认同)
  • 我注意到 Chromium 76 在大约 15,044 个元素及以上时开始出现[糟糕的移位性能](http://www.lonniebest.com/BadShiftPerformance/),而 Firefox 69 则要快得多。 (2认同)