如何在javascript中将文件读入内存时计算好的批量大小?

问题描述 投票:0回答:1

在javascript中,我想读取所有选定的用户文件。

我使用文件夹选择输入字段来获取文件,从导航器变量中获取可用内核的数量,甚至是gb中的RAM。

我正在使用队列算法,所以我为每个可用核心创建一个Web worker任务。

然后我循环遍历每个工人,并从文件列表中切掉batch大小,然后交给工人。

每次工作完成时,它会从文件列表中获取另一个大小为batch的片段,直到没有剩余文件,并且所有工作者都已完成。

我无法弄清楚什么是一个好的batch尺寸值使用。它可以是固定的或基于一些公式。

我发现,如果我有77个文件,批量大小为16可以正常工作,如果我有151324,那么批量大小为300就可以了。但我不想选择一个可以杀死内存的批量大小,但同时也要加快速度。

我还从每个文件中读取最多75千字节。

此外,每个文件都有一个size属性。如果我做任何预先分类,它会有所作为吗?

有谁知道如何做到这一点?

谢谢

javascript performance memory filereader
1个回答
0
投票

这必须进行测试,但是通过使用URL#createObjectURL,理论上可以创建指向磁盘上的文件的直接指针,可供工作人员使用,而无需从主线程复制任何数据。

这意味着您的批量大小可能只是files.length / numberOfWorkers


A rough proof of concept: (作为一个小提琴,因为StackSnippet的null起源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));  
  });
};
© www.soinside.com 2019 - 2024. All rights reserved.