我想將 a 推1送到 Float32Array 的每第四個元素。我目前的解決方案是將所說的 Float32Array 轉換為一個陣列,遍歷它并.splice像這樣應用每四個元素(之后我也將陣列轉換為緩沖區,但這與這個問題無關):
function pushToEveryFourthAndConvertToBuffer(floatArray: Float32Array): Buffer {
const array: number[] = [...floatArray];
for (let i: number = 3; i <= array.length; i = 4) array.splice(i, 0, 1);
return Buffer.from(array);
}
雖然這有效,但它根本沒有性能。我的 Float32Array 有 660000 個條目(因此,回傳的緩沖區有 880000)并且這個函式被大約 100 個不同的 Float32Arrays 呼叫。如果我從函式中洗掉 for 回圈,它運行得更快,所以我可以非常確定我應用元素的方法會導致瓶頸。
有沒有更有效的方法,或者我的 CPU 是否只需要受苦,我是否必須等待很長時間,因為我不想實作多執行緒解決方案?
編輯:我將在這里提供一些輸入和預期輸出來澄清我的問題:
new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0]); // ← input
new Float32Array([0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1]); // ← output
new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]) // ← input
new Float32Array([1, 2, 3, 1, 4, 5, 6, 1, 7, 8, 9]) // ← output
new Float32Array([0.2321, 0.294, 0.1246, 0.9352, 0.87423, 0.11]); // ← input
new Float32Array([0.2321, 0.294, 0.1246, 1, 0.9352, 0.87423, 0.11, 1]); // ← output
uj5u.com熱心網友回復:
執行此操作的非并發方式可能是這樣的
const initial_array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
// from now on we only work with Float32Array. No conversion until the end
const old_floats = new Float32Array(initial_array);
// pre-allocate your new Float32Array because you know how big it needs to be
const new_floats = new Float32Array( Math.ceil(initial_array.length * 4 / 3) );
// fill it with ones
new_floats.fill(1, 0);
// for performance, simple loops are better than array methods
for (let i=0; i<old_floats.length/3; i ) {
let read_start = i*3;
let read_end = read_start 3;
let write_start = i*4;
let four_elements = old_floats.slice(read_start, read_end);
new_floats.set(four_elements, write_start);
}
// now let's convert back to numbers
console.log(new_floats);
對于并發方式,我將創建 4 個異步函式。函式 1 每 3 個值,函式 2 每 3 1,函式 3 每 3 2,函式 4 將簡單地在新陣列的每 4 個值中注入“1”。
最后,您將使用Promise.all()將它們組合在一起
uj5u.com熱心網友回復:
你有什么要使用的理由array.splice嗎?相比其他陣列操作splice是很慢的。
您可以通過使用當前陣列的預期大小創建一個新陣列,然后從舊陣列分配值來執行相同的程序。
function fillArray(floatArray) {
const array = [];
array.length = Math.floor(floatArray.length * 4/3 );
for (let index = 0, negativeIndex = 0; index < array.length; index ) {
if ((index 1) % 4 === 0) {
array[index] = 1;
index ;
negativeIndex--;
}
array[index] = floatArray[index negativeIndex];
}
return Buffer.from(array);
}
在我的瀏覽器中通過 jsbench 運行它顯示您的拼接版本是 3 到 8 次操作/秒,而我的版本是 1,500 到 1,600 次操作/秒。(jsbench 不支持緩沖區,所以你必須跳過最后一步)
如果您想要更簡單的代碼,您可以使用 array.push 而不是定義陣列長度并跟蹤負索引,但這只能執行 500 到 600 次操作/秒,而且您特別在尋找效率。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/337381.html
