2017-09-20 43 views
1

我有一個來源Float32Array,我從中創建了一個輔助Float32Array。我有一個值爲model的序列,我想將其作爲重複序列複製到第Float32Array。我目前正在使用reverse while循環執行此操作。更有效的方法將重複序列複製到TypedArray中?

sequence = [1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 0]; 
n = 3179520; //divisible by sequence length 
modelBuffs = new Float32Array(n); 

var v = modelBuffs.length; 

while(v-=12){ 
    modelBuffs[v-12] = sequence[0]; 
    modelBuffs[v-11] = sequence[1]; 
    modelBuffs[v-10] = sequence[2]; 
    modelBuffs[v-9] = sequence[3]; 

    // YTransform 
    modelBuffs[v-8] = sequence[4]; 
    modelBuffs[v-7] = sequence[5]; 
    modelBuffs[v-6] = sequence[6]; 
    modelBuffs[v-5] = sequence[7]; 

    // ZTransform 
    modelBuffs[v-4] = sequence[8]; 
    modelBuffs[v-3] = sequence[9]; 
    modelBuffs[v-2] = sequence[10]; 
    modelBuffs[v-1] = sequence[11]; 
} 

不幸的是,n可能未知。如果沒有其他解決方案,我可能不得不做一個重要的重構。我希望我可以設置序列一次,並有一個複製到位/重複填充/按位操作重複的初始字節序列。

編輯簡化了示例輸入

+0

正如我所看到的,你有一個模式,但你沒有使用'3,7,11,15'的值。任何具體原因? – Rajesh

+0

@rajesh我從一個更多涉及的例子中截取了這個。具體原因是3,7,11,15是未使用的4×4矩陣的最後一列 – kevzettler

+0

因此,我們應該假設在'N×M'矩陣中,總是不使用'm-1'列? – Rajesh

回答

2

一種快速方法來填充的陣列與重複序列,是加倍緩衝器的長度用於使用所述類型數組的copyWithin()方法每次迭代。您可以使用set()以及爲相同的底層ArrayBuffer創建不同的視圖,但爲此使用前者更爲簡單。

使用例如1234作爲源,第一初始迭代填充將是1:1,或4索引在這種情況下:

1234 

從那裏,我們將使用目標緩衝區作爲源對於其餘的填充所以第二次迭代填充8個索引:

12341234 

第三次迭代填充16個指數:

1234123412341234 

第四次迭代填充32個指數:

12341234123412341234123412341234 

等等。

如果最後一個段的長度與2的冪不匹配,可以簡單地在最後一個填充和剩餘在緩衝區中的長度之間做一個差異,並將其用於最後一次迭代。

如果數組是很長的它顯然需要一些時間不管。在這些情況下,您可以考慮將Web Worker與新的SharedArrayBuffer結合使用,以便您可以在不同的進程中進行復制,而不必複製或傳輸數據。從這裏獲得的收益僅僅是主線程不會受到處理緩衝區的小開銷的阻礙,因爲copyWithin()的內部對於其目的已經是相對最佳的。缺點是異步方面與事件系統的開銷相結合(例如:這取決於這是否有用)。

一個不同的方法是使用WebAssembly在C/C++中編寫緩衝區填充代碼,編譯和公開方法來獲取源緩衝區和目標緩衝區,然後從JavaScript調用它。這種情況我沒有任何例子。

在這兩種情況下,您都會遇到(不是那麼多)舊版瀏覽器的兼容性問題。

+0

這是非常好的謝謝! – kevzettler