【问题标题】:process bunch of string effective处理字符串有效
【发布时间】:2013-05-16 05:47:53
【问题描述】:

我需要从一个128M的chuck文件中读取一些数据,然后对于每一行,我都会做一些处理,天真的方法是使用split将字符串转换为行集合,然后处理每一行,但也许这不是有效的,因为它会创建一个简单地存储临时结果的集合,这可能是昂贵的。有没有更好的方法?

文件很大,所以我启动了几个线程,每个线程会拾取128个chuck,在下面的脚本中rawString是一个128M的chuck。

randomAccessFile.seek(start)
randomAccessFile.read(byteBuffer)
val rawString = new String(byteBuffer)
val lines=rawString.split("\n")
for(line <- lines){
    ...
}

【问题讨论】:

    标签: performance scala collections


    【解决方案1】:

    最好是逐行阅读:

    import scala.io.Source
    for(line <- Source.fromFile("file.txt").getLines()) {
      ...
    }
    

    【讨论】:

    • 由于文件比较大,我把文件分成128个一个chuck,每个chuck一个线程处理,所以不能使用Source.fromFile("file.txt")跨度>
    • stackoverflow.com/questions/13843015/… 看起来很有帮助。
    【解决方案2】:

    我不确定您将如何处理块开头和结尾的行尾。我将把它留给你来解决——这个解决方案捕获了两边由\n分隔的所有内容。

    无论如何,假设 byteBuffer 实际上是一个字节数组而不是 java.nio.ByteBuffer,并且您可以只处理 Unix 行编码,您会想要

    def lines(bs: Array[Byte]): Array[String] = {
      val xs = Array.newBuilder[Int]
      var i = 0
      while (i<bs.length) {
        if (bs(i)=='\n') xs += i
        i += 1
      }
      val ix = xs.result
      val ss = new Array[String](0 max (ix.length-1))
      i = 1
      while (i < ix.length) {
        ss(i-1) = new String(bs, ix(i-1)+1, ix(i)-ix(i-1)-1)
        i += 1
      }
      ss
    }
    

    当然,这是相当长且混乱的代码,但如果您真的担心性能,那么这种事情(大量使用基元上的低级操作)是可行的方法。 (这也只需要大约 3 倍的磁盘块内存,而不是大约 5 倍(用于大部分/完全 ASCII 数据),因为您不需要完整的字符串表示。)

    【讨论】:

    • 当使用你的方法时:val stringArray=lines(byteBuffer),它会抛出 java.lang.OutOfMemoryError: Java heap space 的错误。原来的方法没有这个错误。
    • @DanielWu - 我将数组分配方法更改为我最初想要的。那应该可以解决它(不会浪费空间)。
    • 我读取的文件大小为128M,最大堆为16G,但由于memory.java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange( Unknown Source) at java.lang.String.(Unknown Source) at java.lang.StringBuilder.toString(Unknown Source)
    • 我为每处理 1000 行打印了一些信息,发现当处理超过 10k 行时它会耗尽内存。 while (i
    • @DanielWu - 抱歉,限制错误 - 它需要长度,而不是结束索引。现已修复。
    猜你喜欢
    • 2020-06-01
    • 2017-07-07
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 2019-03-22
    相关资源
    最近更新 更多