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

如何在Java8中并行读取文件的所有行,java,parallel-processing,java-8,Java,Parallel Processing,Java 8,我希望尽可能快地将1 GB大文件的所有行读取到流中。目前我正在使用文件(path).lines()来实现这一点。解析完文件后,我正在进行一些计算(map()/filter()) 起初我以为这已经并行完成了,但似乎我错了:在我的双CPU笔记本电脑上读取文件时,大约需要50秒。但是,如果我使用bash命令分割文件,然后并行处理它们,只需要大约30秒 我尝试了以下组合: 单文件,无平行线()流约50秒 单个文件,文件(..).lines().parallel().[…]约50秒 两个文件,没有平行线(

我希望尽可能快地将1 GB大文件的所有行读取到
流中
。目前我正在使用
文件(path).lines()
来实现这一点。解析完文件后,我正在进行一些计算(
map()
/
filter()

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

我尝试了以下组合:

  • 单文件,无平行线()流约50秒
  • 单个文件,
    文件(..).lines().parallel().[…]
    约50秒
  • 两个文件,没有平行线()大约30秒
  • 两个文件,
    文件(..).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
    
    所以我的问题是,Java8JDK中是否有任何类或函数可以并行读取所有行而不必首先拆分它?例如,如果我有两个CPU核,
    第一行阅读器应该从第一行开始,第二行从第
    (totalines/2)+1行开始,您可能会从中找到一些帮助。尝试并行化文件的实际读取可能是错误的,因为最大的减速将是您的文件系统(即使在SSD上)


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

    使用bash拆分文件是什么意思?此外,您必须读取文件才能找到行。它不能只知道行终止符在哪里。@SotiriosDelimanolis您可以跳转到文件中的任意点,查找第一个新行并以这种方式拆分,而无需首先处理整个段中的所有数据。在bash中,您可以使用
    split-l#lines
    ,将其与
    wc-l
    组合,将其拆分为两半。迈克尔·佩奇明白我的意思:)@michael,当然,但你必须重建通往终点线的一切。。。。可能真正的困难在于文件太大,无法放入缓存,因此必须从磁盘读取。但是磁盘只有一个寻道头(通常),因此您可以在两半之间进行寻道(非常昂贵),或者从一端顺序读取。由于对头部的多重需求,随着N的增加,价格可能会变得更糟。因此,随着N的增加,您需要支付搜索时间成本,这可能会影响并行性。我的猜测是,你已经简单地尝试了不同的N;缓冲区/开销太多,无法轻松猜测最佳点在哪里。对于小N,我改变了用于测试的方法,我似乎错了,因为在对结果流执行最终操作(forEach(System.out::println))之前,我意外地将结果大小限制为200。实际上,是Files.lines(Path)将给定文件作为顺序流读取。此外,大部分时间实际上都花在读取文件上,而不是计算上,加上我遇到了一些GC问题。我对Files.lines(Path).toArray()与使用MappedByteBuffer(只读,0,file.size)的方法进行了计时。结果实际上是完全相同的,MappedByteBuffer在这里和那里都慢了一点。@user3001,您的最终分辨率是什么?实际上我发现这在很大程度上取决于您如何处理流中的数据。最后,我使用了顺序流来避免垃圾收集问题。