BLOBの内容を既存のSharedArrayBufferに読み込む最も効率的な方法を見つけようとしているのは、バッファがポップされるのを待っているワーカーだからです。私の場合は、SharedArrayBufferが少なくともBLOBの内容全体を保持するのに十分な長さであることを保証できます。私が思いついた最善のアプローチは次のとおりです:BLOBの内容を既存のSharedArrayBufferに読み込む
これは、特に読み込み中のブロブが比較的大きい場合、非効率的なようです。
BLOBの内容を既存のSharedArrayBufferに読み込む最も効率的な方法を見つけようとしているのは、バッファがポップされるのを待っているワーカーだからです。私の場合は、SharedArrayBufferが少なくともBLOBの内容全体を保持するのに十分な長さであることを保証できます。私が思いついた最善のアプローチは次のとおりです:BLOBの内容を既存のSharedArrayBufferに読み込む
これは、特に読み込み中のブロブが比較的大きい場合、非効率的なようです。
Blob
は、Transferable
オブジェクトではありません。また、FileReader
には.readAsSharedArrayBuffer
メソッドがありません。しかし
、あなただけのする必要がある場合は、同時に複数の作業員からBlob
を読んで、私は、複数の労働者でこれをテストしていませんが、あなたはURL.createObjectURL()
とfetch
でこれを達成できると信じて:
// === main thread ===
let objectUrl = URL.createObjectURL(blob);
worker1.postMessage(objectUrl);
worker2.postMessage(objectUrl);
// === worker 1 & 2 ===
self.onmessage = msg => {
fetch(msg.data)
.then(res => res.blob())
.then(blob => {
doSomethingWithBlob(blob);
});
};
そうでない場合私が知る限り、ファイルからのデータをSharedArrayBuffer
にロードする効率的な方法は実際にはありません。
また、メインスレッドから単一のワーカーにブロブのチャンクを転送する方法も提供します。私の使用例では、ファイルは大きすぎるため、コンテンツ全体を単一の配列バッファに読み込むことはできません(共有されているかどうか)。.slice
を使用してチャンクを処理します。このような何かは、あなたが使用して複数の経由でストリーム状に単一のワーカーに.postMessage
通話をデータのトンをお届けできるようになるTransferable
ArrayBuffer
:これは、メインスレッドでArrayBuffer
にデータのチャンクを読み込みます
// === main thread ===
let eof = false;
let nextBuffer = null;
let workerReady = true;
let read = 0;
function nextChunk() {
let end = read + chunkSize;
if(end >= file.length) {
end = file.length;
eof = true;
}
let slice = file.slice(read, end);
read = end;
fr.readAsArrayBuffer(slice);
}
fr.onload = event => {
let ab = event.target.result;
if(workerReady) {
worker.postMessage(ab, [ab]);
workerReady = false;
if(!eof) nextChunk();
}
else {
nextBuffer = ab;
}
};
// wait until the worker finished the last chunk
// ... otherwise we'll flood main thread's heap
worker.onmessage = msg => {
if(nextBuffer) {
worker.postMessage(nextBuffer, [nextBuffer]);
nextBuffer = null;
}
else if(!eof && msg.ready) {
nextChunk();
}
};
nextChunk();
// === worker ===
self.onmessage = msg => {
let ab = msg.data;
// ... do stuff with data ...
self.postMessage({ready:true});
};
それをワーカーに転送し、ワーカーが以前のチャンクを処理するのを待つ間に次のチャンクをメモリに読み込みます。これにより、基本的に、両方のスレッドが常にビジー状態を保つことが保証されます。