我希望尽快将1 GB大文件的所有行读入Stream<String>
。目前我正在使用Files(path).lines()
。解析文件后,我正在进行一些计算(map()
/ filter()
)
起初我以为这已经是并行完成了,但似乎我错了:
在原样读取文件时,我的双CPU笔记本电脑需要大约50秒。
但是,如果我使用bash命令拆分文件然后并行处理它,它只需要大约30秒。
我尝试了以下组合:
Files(..).lines().parallel().[...]
~50秒Files(..).lines().parallel().[...]
~30秒我用大致相同的结果(1或2秒)多次运行这4次。 [...]
只是一个地图和过滤器链,最后有一个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
行开始。
答案 0 :(得分:6)
您可以从this post找到一些帮助。尝试并行化文件的实际读取可能是错误的树,因为最大的减速将是您的文件系统(即使在SSD上)。
如果你在内存中设置一个文件通道,你应该能够以极快的速度从那里并行处理数据,但是你很可能不需要它,因为你会看到一个巨大的速度增加。