去一个数组中添加另外另外一个数组中的元素,两种方式比较(拼接和push)

往一个数组中添加另外另外一个数组中的元素,两种方式比较(拼接和push)
jQuery里面有一段源码:
Array.prototype.push.apply(someArray, otherArray);
这个做法依赖两点:
1、apply方法的第二个参数是数组的情况下,这个数组参数会作为apply的方法的参数列表(arguments);
2、push方法接受可变参数列表:array.push(item1 [, item2 ... [, itemN]])
按照源码注释的说法,“super-fast way to populate an object with array-like properties”,正好最近自己在写一个jQuery插件时需要往一个数组中添加另外一个数组中的元素,我采用的方法是使用Array的concat方法拼合另外一个数组,再将生成的数组重新赋值给原先的数组变量:
someArray = someArray.concat(otherArray)
而我之前一直纠结于此方法会产生一个额外的数组变量,而且第一个数组长度越大性能开销就越大(需要复制引用),看到jQuery中的这段源码便很是欢喜,打算换掉之前插件中的这种处理方式。
不过为保险起见,我还是先做了两个实验
第一个实验:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <script type="text/javascript">
      var rightArray = [];
      window.onload = function() {
        for (var i = 0; i < 1000000; i++) {
          rightArray.push(i);
        }
      };
      function doPush() {
        var array = [];
        var before = new Date().getTime();
        Array.prototype.push.apply(array, rightArray)
        var after = new Date().getTime();
        document.getElementById("result").innerHTML = (after - before);
      }
      function doConcat() {
        var array = [];
        var before = new Date().getTime();
        array = array.concat(rightArray);
        var after = new Date().getTime();
        document.getElementById("result").innerHTML = (after - before);
      }
    </script>
  </head>
  <body>
      <span id="result"></span>
      <input type="button" value="pushAll" onclick="doPush();" />
      <input type="button" value="concat" onclick="doConcat();" />
  </body>
</html>
实验结果:
1、在ff3.0.9下,concat的平均耗时在130毫秒左右,applypush的方式平均耗时在70毫秒左右
2、在ie8下,concat的平均耗时在270毫秒左右,而applypush的方式平均耗时居然是两秒…………囧冏
第二个实验针对在第一个数组长度不同的情况下两种方式的差异,代码就不贴了,直接说结论,在ff下,concat方式的耗时确实会随着第一个数组长度的增加而增加,而push的方式则影响不大,ie下我已经没勇气试了。

结论
应该说jQuery的这种方式在ff下确实可以说是super-fast,但是在ie8下的测试数据让我实在无语,我不知道是不是我实验方式有问题……
看来我还是继续在我的代码中使用concat吧,而且我写的那个插件不可能出现这么大数据量的场景,这点性能差异就忽略吧。
1 楼 caii 2009-04-23  
super-fast way to populate an object with array-like properties
让一个对象有“类数组”属性 超快的方法。

帮你测了下,在GOOGLE浏览器中,concat也不比[].push 慢。
2 楼 keshin 2009-04-23  
caii 写道
super-fast way to populate an object with array-like properties
让一个对象有“类数组”属性 超快的方法。

帮你测了下,在GOOGLE浏览器中,concat也不比[].push 慢。

呵呵,多谢了,手头没有chrome