2017-06-26 10 views
0

BLOBの内容を既存のSharedArrayBufferに読み込む最も効率的な方法を見つけようとしているのは、バッファがポップされるのを待っているワーカーだからです。私の場合は、SharedArrayBufferが少なくともBLOBの内容全体を保持するのに十分な長さであることを保証できます。私が思いついた最善のアプローチは次のとおりです:BLOBの内容を既存のSharedArrayBufferに読み込む

これは、特に読み込み中のブロブが比較的大きい場合、非効率的なようです。

答えて

0

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通話をデータのトンをお届けできるようになるTransferableArrayBuffer:これは、メインスレッドで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}); 
}; 

それをワーカーに転送し、ワーカーが以前のチャンクを処理するのを待つ間に次のチャンクをメモリに読み込みます。これにより、基本的に、両方のスレッドが常にビジー状態を保つことが保証されます。

関連する問題