簡體   English   中英

在javascript中將typedarray復制到數組的最快方法?

[英]Fastest way to copy typedarray to array in javascript?

最簡單的方法是使用 for 循環:

function copy(a, t, start, end) {
    for (var j = start; j < end; j++) {
        a[j] = t[j];
    }
}

我認為更好的實現是使用點差 + 拼接:

function copy_splice(a, t, start, end) {
    a.splice(start, end - start, ...t.slice(start, end));
}

但是,當我使用以下代碼對此進行測試時,性能明顯變差:

function randArray(length) {
    var result = [];
    for (var j = 0; j < length; j++) {
        result.push(Math.floor(60000 * Math.random()));
    }
    return result;
}

function test_func(copy_func) {
    [10, 100, 1000, 100000].forEach(function (length) {
        var a = randArray(length);
        const t = new Int32Array(randArray(length));
        const start = length / 10;
        const end = length / 2;

        const time_start = performance.now();
        for (var repeats = 0; repeats < 500; repeats++) {
            copy_func(a, t, start, end);
        }
        const time_end = performance.now();
        console.log(copy_func.name + ' timing: ' + (time_end - time_start));
    });
}

// Test first
var a1 = randArray(100);
var a2 = a1.slice();
var t = new Int32Array(randArray(100));
copy(a1, t, 10, 50);
copy_splice(a2, t, 10, 50);
console.assert(a1.reduce((a, b) => a + b, 0) == a2.reduce((a, b) => a + b, 0));


test_func(copy);
test_func(copy_splice);

Firefox 中的結果:

copy timing: 1
copy timing: 0
copy timing: 37
copy_splice timing: 4
copy_splice timing: 20
copy_splice timing: 1140

在 Nodejs 中的結果:

copy timing: 0.08499000035226345
copy timing: 1.3703359998762608
copy timing: 0.8646280001848936
copy timing: 24.584946000017226
copy_splice timing: 0.8248800002038479
copy_splice timing: 2.532259000465274
copy_splice timing: 5.594846999272704
copy_splice timing: 529.5111650004983

所以:

  1. 還有比上面提到的更好的實現嗎?
  2. (可選)為什么數組傳播 + .splice在這里表現更差?

通常,簡單的舊式for循環會勝過其他替代方法。 傳播語法表現更差的原因是有很多開銷:

  1. t.slice()創建一個新數組
  2. ...調用數組迭代器以從該數組中檢索值
  3. 所有這些參數都放在splice函數調用的上下文中的堆棧上
  4. splice將元素一一替換,很像for循環的解決方案
  5. splice還將替換的元素收集到一個新數組中,並返回該數組。

如您所見, for循環解決方案只需要處理第 4 點,而不需要處理與其他點相關的任何內容。

可能一個智能 JavaScript 引擎可以優化掉上面描述的一些冗余工作,但是你看到的證據證明(目前)這種優化並沒有帶來普通for循環的效率。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM