高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

Faster Array Concatenation in AS3

前不久在Grant Skinner大人的twitter上看到這個:

Just discovered a handy trick for merging two arrays in JS: arr1.push.apply(arr1, arr2);

真神奇,原來Function.apply還可以這樣玩,而且這招似乎在AS3上也可行,直接寫幾行程式碼測一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function test_concat():void
{
  trace("== TEST Array Concat ==");
  var array1:Array = [1, 2, 3];
  var array2:Array = ['a', 'b', 'c'];
  var timer_start = getTimer();
  for (var i:int = 0; i< 10000; i++)
  {
      array1 = array1.concat(array2);
  }
  var timer_end = getTimer();
  trace("the length of array1 is : " + array1.length);
  trace("== " + (timer_end - timer_start) + " miniseconds ==");
}

function test_push_and_apply():void
{
  trace("== TEST Array Push and Apply ==");
  var array1:Array = [1, 2, 3];
  var array2:Array = ['a', 'b', 'c'];
  var timer_start = getTimer();
  for (var i:int = 0; i< 10000; i++)
  {
      array1.push.apply(array1, array2);
  }
  var timer_end = getTimer();
  trace("the length of array1 is : " + array1.length);
  trace("== " + (timer_end - timer_start) + " miniseconds ==");
}

// 測試
test_concat();
trace("");
test_push_and_apply();

我的環境:

  • Macbook Pro
  • CPU : Intel Core 2 Duo 2.4 GHz
  • RAM : 4 GB

執行結果:

== TEST Array Concat ==
the length of array1 is : 30003
== 4119 miniseconds ==

== TEST Array Push and Apply ==
the length of array1 is : 30003
== 5 miniseconds ==

array1最後結果內容是一樣的,但花的時間差非常大,我想這其中主要的差異應該是在於Array.concat每次都會產生一個新的array,而且還得再assign給原來的array的緣故。

後來還有看到這篇,野中さん有在wonderfl上做了幾個實驗,結果發現跟這兩個array的大小有關。不過在我的機器上好像在試不出來差異,不知道是不是我哪邊有錯,即使調整兩個array的大小,Function.apply的速度都是遠大於Array.concat的。

update: 是我自己耍笨,測試數字請見連結裡野中さん的那三個測試。

I may be wrong, please correct me if there’s anything wrong :)

Comments