簡體   English   中英

將重復序列復制到TypedArray的更有效方法?

[英]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.

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