[英]More efficient way to copy repeating sequence into TypedArray?
我有一個源Float32Array
,可Float32Array
創建輔助Float32Array
。 我有一個值序列model
,我想將其作為重復序列復制到輔助Float32Array
。 我目前正在使用反向while循環進行此操作。
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
可能是未知的。 如果沒有其他解決方案,我可能必須做一個重要的重構。 我希望我可以設置一次序列,並且有一個副本/重復填充/按位操作來重復初始字節序列。
編輯簡化了示例輸入
一種用重復序列填充數組的快速方法是使用類型化數組的copyWithin()
方法為每次迭代加倍緩沖區長度。 您還可以通過為相同的基礎ArrayBuffer
創建一個不同的視圖來使用set()
,但是使用前者更容易實現此目的。
使用例如1234
作為源,第一個初始迭代填充將為1:1,在這種情況下為4個索引:
1234
從那里,我們將目標緩沖區用作剩余填充的源,因此第二次迭代將填充8個索引:
12341234
第三次迭代填充16個索引:
1234123412341234
第四次迭代填充了32個索引:
12341234123412341234123412341234
等等。
如果最后一段的長度不等於2的冪,則可以簡單地在最后一次填充和緩沖區中剩余的長度之間進行區分,並將其用於最后一次迭代。
var srcBuffer = new Uint8Array([1,2,3,4]), // any view type will do dstBuffer = new Uint8Array(1<<14), // 16 kb len = dstBuffer.length, // important: use indices length, not byte-length sLen = srcBuffer.length, p = sLen; // set initial position = source sequence length var startTime = performance.now(); // step 1: copy source sequence to the beginning of dest. array // todo: dest. buffer might be smaller than source. Check for this here. dstBuffer.set(srcBuffer); // step 2: copy existing data doubling segment length per iteration while(p < len) { if (p + sLen > len) sLen = len - p; // if not power of 2, truncate last segment dstBuffer.copyWithin(p, 0, sLen); // internal copy p += sLen; // add current length to offset sLen <<= 1; // double length for next segment } var time = performance.now() - startTime; console.log("done", time + "ms"); console.log(dstBuffer);
如果數組很長,則無論如何顯然會花費一些時間。 在這些情況下,您可以考慮將Web Worker與新的SharedArrayBuffer
一起使用,以便可以在不同的過程中進行復制,而不必在數據之間SharedArrayBuffer
復制或傳輸數據。 從中獲得的好處僅僅是,主線程不會因為處理緩沖區而copyWithin()
很少的開銷就被阻塞了,因為copyWithin()
的內部對於它的目的已經是相對最佳的。 缺點是異步方面,再加上事件系統的開銷(例如:這取決於是否有用)。
另一種不同的方法是使用WebAssembly ,在其中以C / C ++編寫緩沖區填充代碼,編譯並公開方法以獲取源緩沖區和目標緩沖區,然后從JavaScript調用該方法。 對於這種情況,我沒有任何示例。
在這兩種情況下,您都會遇到與(不是那么多)舊版瀏覽器的兼容性問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.