file - Scala快速文本文件读取并上传到内存

标签 file scala io scalaz scalaz-stream

在 Scala 中,读取文本文件并将其上传到数组中,常用的方法是

scala.io.Source.fromFile("file.txt").getLines.toArray

特别是对于非常大的文件,是否有一种更快的方法,可能是先将字节块读取到内存中,然后通过换行符将它们拆分? (有关常用方法,请参阅 Read entire file in Scala。)

非常感谢。

最佳答案

性能问题与读取数据的方式无关。它已经被缓冲了。在您真正遍历这些行之前,什么都不会发生:

// measures time taken by enclosed code
def timed[A](block: => A) = {
  val t0 = System.currentTimeMillis
  val result = block
  println("took " + (System.currentTimeMillis - t0) + "ms")
  result
}

val source = timed(scala.io.Source.fromFile("test.txt")) // 200mb, 500 lines
// took 0ms

val lines = timed(source.getLines)
// took 0ms

timed(lines.next) // read first line
// took 1ms

// ... reset source ...

var x = 0
timed(lines.foreach(ln => x += ln.length)) // "use" every line
// took 421ms

// ... reset source ...

timed(lines.toArray)
// took 915ms

考虑到我的硬盘每秒 500 mb 的读取速度,200 mb 的最佳时间将是 400 毫秒,这意味着除了不将迭代器转换为数组之外,没有改进的余地。

根据您的应用程序,您可以考虑直接使用迭代器而不是数组。因为在内存中使用如此庞大的数组肯定会出现性能问题。

编辑 :根据您的评论,我假设您想进一步转换数组(也许正如您所说的那样将行拆分为列,您正在阅读数字数组)。在这种情况下,我建议在阅读时进行转换。例如:
source.getLines.map(_.split(",").map(_.trim.toInt)).toArray


source.getLines.toArray.map(_.split(",").map(_.trim.toInt))

(对我来说是 1.9s 而不是 2.5s)
因为您不会将整个巨大数组转换为另一个数组,而是将每一行单独转换为一个数组(仅使用一半的堆空间)。此外,由于读取文件是一个瓶颈,在读取时进行转换的好处是可以提高 CPU 利用率。

关于file - Scala快速文本文件读取并上传到内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23007646/

相关文章:

php - 如何使用javascript检查是否选择了文件?

python - 如何在 Python 中从流追加到文件而不是覆盖

scala - 从 TypeTag 和方法中获取精确的返回类型

c - 如何从文件中读取整数到 C 中的一维数组

c - C 中 FILE 结构中的 r+ 是什么?

scala - 捕获可变参数参数的类型

scala - 如何获取 map 的子集?

java - java web应用程序中的文件上传显示文件未找到异常

java - 流氓黑盒 java 应用程序不响应标准输入重定向

javascript - 从另一个 JavaScript 编写一个 JavaScript 文件