2017-12-19 17 views
0

javascriptでは、選択したすべてのユーザーファイルを読み込みたいです。JavaScriptを使用してメモリにファイルを読み込むときのバッチサイズを計算するにはどうすればよいですか?

私はnavigator変数から、ファイルを取得するためにフォルダ選択入力フィールドを使用し、使用可能なコアの量、およびgb単位のRAMを取得します。

私はキューアルゴリズムを使用しているので、使用可能なコアごとにWebワーカータスクを作成します。

次に、すべてのワーカーをループし、ファイルリストからサイズをbatchにスライスし、ワーカーに与えます。

作業員が終了するたびに、ファイルが残っていなくてもすべての作業者が終了するまで、ファイルリストからサイズbatchの別のスライスを取ります。

使用するのに良いbatchの値がわかりません。これは固定式でも、数式に基づいていてもかまいません。

ファイルが77個ある場合、バッチサイズは16で、151324の場合は300のバッチサイズが問題ありません。しかし、私は、メモリを破壊するバッチサイズを選択するのではなく、同時にそれを速くすることを望んでいます。

また、私は各ファイルから最大75キロバイトを読みました。

また、各ファイルにはサイズプロパティがあります。もし私が何らかの前兆をしたら、それは違いをもたらすだろうか?

誰でもこれを行う方法を知っていますか?

おかげ

答えて

0

これをテストする必要があるが、URL#createObjectURLを使用することによって、あなたは理論的には、メインスレッドから任意のデータをコピーせずに、あなたの労働者に利用可能なディスク上のファイルへの直接のポインタを、作成することができます。

つまり、お客様のバッチサイズは、単にfiles.length/numberOfWorkersとなります。


A rough proof of concept:
(フィドルなどStackSnippetのnull originedのiframeがこのトリックを不可能にするので...)労働者で

:メインページで

self.onmessage = e => { 
    Promise.all(
    e.data.map(async (url)=> 
     fetch(url).then(r=>r.blob()) 
    // here you can do whatever you have to do with the file 
     .then(file => new FileReaderSync() 
     .readAsText(file.slice(0,75)) 
     ) 
    ) 
) 
    .then(console.log) 
    .catch(console.error); 
}; 
</script> 

// workers is an Array containing your WebWorkers 
inp.onchange = e => { 
    const urls = [...inp.files] 
    .map(file => URL.createObjectURL(file)); 
    const batchSize = Math.ceil(urls.length/(navigator.hardwareConcurrency)); 
    workers.forEach((worker, i) => { 
    worker.postMessage(urls.slice(i*batchSize, i*batchSize + batchSize)); 
    }); 
}; 
関連する問題