我想尽快将 1 GB 大文件的所有行读入 Stream<String>
.目前我正在使用 Files(path).lines()
为了那个原因。解析文件后,我进行了一些计算 ( map()
/filter()
)。
起初我以为这已经是并行完成的,但似乎我错了:按原样读取文件时,在我的双 CPU 笔记本电脑上大约需要 50 秒。但是,如果我使用 bash 命令拆分文件,然后并行处理它们,则只需要大约 30 秒。
我尝试了以下组合:
- 单个文件,无平行线()流 ~ 50 秒
- 单个文件,
Files(..).lines().parallel().[...]
~ 50 秒 - 两个文件,没有平行线() strean ~ 30 秒
- 两个文件,
Files(..).lines().parallel().[...]
~ 30 秒
我多次运行这 4 次,结果大致相同(相差 1 或 2 秒)。 [...]
仅是映射和过滤器链,带有 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
行开始.
最佳答案
您可能会从 this post 中找到一些帮助.尝试并行化文件的实际读取可能是错误的树,因为最大的减速将是您的文件系统(即使在 SSD 上)。
如果您在内存中设置一个文件 channel ,您应该能够从那里以极快的速度并行处理数据,但您可能不需要它,因为您会看到速度大幅提高。
关于java - 如何在 Java 8 中并行读取文件的所有行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25711616/