处理串有效的字符串

时间:2013-05-16 05:47:54

标签: performance scala collections

我需要从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){
    ...
}

2 个答案:

答案 0 :(得分:2)

最好逐行阅读文字:

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

答案 1 :(得分:1)

我不确定你要在块的开头和结尾处跟踪行的尾部。我会留给你弄清楚 - 这个解决方案通过\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数据),因为你不需要周围的完整字符串表示。)