在Ruby中解析大文件的最快方法

Dav*_*iov 7 ruby

我有一个约150mb的简单文本文件.我的代码将读取每一行,如果它匹配某些正则表达式,它将被写入输出文件.但是现在,只需要很长时间来遍历文件的所有行(几分钟)就可以了

File.open(filename).each do |line|
  # do some stuff
end
Run Code Online (Sandbox Code Playgroud)

我知道这是循环文件的线路需要一段时间,因为即使我对"#do some stuff"中的数据什么都不做,它仍然需要很长时间.

我知道有些unix程序几乎可以立即解析像这样的大文件(比如grep),所以我想知道为什么ruby(MRI 1.9)需要这么长时间才能读取文件,有没有办法让它更快?

tad*_*man 5

进行比较并不公平,grep因为这是一个高度调整的实用程序,它只扫描数据,不存储任何数据。当您使用 Ruby 读取该文件时,您最终会为每一行分配内存,然后在垃圾回收周期中释放它。grep是一个非常精益和刻薄的正则表达式处理机器。

您可能会发现可以通过使用外部程序(例如grep调用 usingsystem或通过管道工具)来达到您想要的速度:

`grep ABC bigfile`.split(/\n/).each do |line|
  # ... (called on each matching line) ...
end
Run Code Online (Sandbox Code Playgroud)

  • Ruby 必须为每一行分配内存,然后销毁该内存,这与 grep 仅扫描一个小的滑动缓冲区相比,需要做更多的工作。 (3认同)

ste*_*lag 2

File.readlines.each do |line|
  #do stuff with each line
end
Run Code Online (Sandbox Code Playgroud)

将整个文件读入一组行中。它应该快很多,但需要更多内存。

  • [基准测试显示,对于大文件,“readlines”不如使用“foreach”快](http://stackoverflow.com/questions/25189262/why-is-slurping-a-file-bad)。它也是不可扩展的。使用“foreach”而不是“readlines”,代码将保持不变,只是扩展,并且读取的文件越大,运行速度就越快。 (4认同)