Faster Array Concatenation in AS3

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

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

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

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();

我的環境:

執行結果:

== 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 :)