如何在 Java 8 中并行读取文件的所有行

2022-09-02 14:04:45

我想尽可能快地将1 GB大文件的所有行读取到.目前我正在使用它。解析文件后,我正在做一些计算(/)。Stream<String>Files(path).lines()map()filter()

起初,我以为这已经并行完成,但似乎我错了:当按原样读取文件时,在我的双CPU笔记本电脑上大约需要50秒。但是,如果我使用bash命令拆分文件,然后并行处理它们,则只需要大约30秒。

我尝试了以下组合:

  1. 单个文件,无平行线()流~50秒
  2. 单个文件,约 50 秒Files(..).lines().parallel().[...]
  3. 两个文件,无平行线() strean ~ 30 秒
  4. 两个文件,约 30 秒Files(..).lines().parallel().[...]

我多次运行这4次,结果大致相同(1或2秒)。仅是一个地图和过滤器链,末尾有 a 来触发评估。[...]toArray(...)

结论是,使用 .由于并行读取两个文件所需的时间较短,因此拆分文件可以提高性能。但是,似乎整个文件都是按顺序读取的。lines().parallel()

编辑:
我想指出我使用SSD,所以几乎没有寻求时间。该文件总共有1658652行(相对较短)。在 bash 中拆分文件大约需要 1.5 秒:

   time split -l 829326 file # 829326 = 1658652 / 2
   split -l 829326 file  0,14s user 1,41s system 16% cpu 9,560 total

所以我的问题是,Java 8 JDK中是否有任何类或函数可以并行读取所有行,而不必先拆分它?例如,如果我有两个CPU内核,则第一行读取器应从第一行开始,第二行读取器应从行开始。(totalLines/2)+1


答案 1

您可能会从这篇文章中找到一些帮助。尝试并行化文件的实际读取可能会叫错树,因为最大的减速将是您的文件系统(即使在SSD上也是如此)。

如果您在内存中设置了文件通道,则应该能够以极快的速度从那里并行处理数据,但很可能您不需要它,因为您将看到速度大幅提高。


答案 2

推荐