在循环中使用Array.pop()比Array.length = 0快50倍,这是真的吗?

4
我的问题源自这里的Jsperf测试:http://jsperf.com/the-fastest-way-to-truncate-an-array/7 设置代码如下:
Benchmark.prototype.setup = function() {
  var test_array = [];

  for (var j=0; j< 10000; j++){
    test_array[j] = 'AAAAAAAAAA';
  }

};

还有测试:

// Array.slice() method
result = test_array.slice(0,100);

// Array.splice() method
test_array.splice(100);

// Modifying Array.length
test_array.length = 100;

// Array.pop() method
while (test_array.length > 100) test_array.pop();

JSPerf的结果显示,Array.pop()方法比其他方法快得多,有些实现甚至快了80倍。

这是怎么回事呢?在循环中使用Array.pop()真的比其他测试要快这么多吗?还是我没有看到测试中的缺陷?


6
你的测试存在缺陷。它主要运行在空数组上,此时 while 循环条件比方法调用更快。 - Bergi
对于那些好奇我是如何找到这个的:http://chat.stackoverflow.com/transcript/message/21166582#21166582 - jdphenix
嗯,@Aaditmshah被自己的测试结果愚弄了... - Bergi
你是否正确地读取了结果?Pop 是最需要进行操作才能达到相同结果的,对吗? - MaxZoom
1
为什么数组是空的? - user1428716
2
这个怎么样?http://jsperf.com/the-fastest-way-to-truncate-an-array/10 - zerkms
1个回答

8
JsPerf对每个设置运行多次测试。这意味着您只需要一次针对10000个元素的数组进行测试,在随后的(非常多)运行中,数组中只剩下100个条目。
因此,while循环的条件非常快:一个单独的、可能被缓存的属性访问和比较。所有其他测试案例都调用一个方法或setter方法(该方法内部仅执行此测试,可能还有更多操作)。
像@zerkms创建的那样正确的测试案例在每次迭代中都使用一个新数组 - 这就是您想要测试的东西。随着执行更多(相似的)工作,解决方案之间的相对差异将变得更小,但您仍然可以注意到趋势。当然,即使这些也容易受到编译器的优化,因此您永远无法确保......

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接