如何快速切片和切块大数据文件?

时间:2008-09-23 21:41:21

标签: ruby data-files

我想以一种相当快速有效的方式切割和切割大型数据文件,直到演出。如果我使用UNIX的“CUT”之类的东西,它甚至在CYGWIN环境中都非常快。

我已经尝试开发和基准化各种Ruby脚本来处理这些文件,并且总是最终得到冰川结果。

你会在Ruby中做些什么来使这不是那么慢的狗?

4 个答案:

答案 0 :(得分:2)

这个问题让我想起蒂姆布雷的Wide Finder project。使用Ruby读取Apache日志文件的最快方法是找出最多的文章,这个脚本是用这个脚本编写的:

counts = {}
counts.default = 0

ARGF.each_line do |line|
   if line =~ %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }
     counts[$1] += 1
   end
end

keys_by_count = counts.keys.sort { |a, b| counts[b] <=> counts[a] }
keys_by_count[0 .. 9].each do |key|
    puts "#{counts[key]}: #{key}"
end
  

在去年的1.67Ghz PowerBook上,这段代码用了7½秒的CPU,经过了13½秒,处理了一百万,并且更改了四分之一左右的记录。

答案 1 :(得分:1)

我猜你的Ruby实现在处理之前正在读取整个文件。 Unix的剪切通过一次读取一个字节并且立即转储到输出文件来工作。当然有一些缓冲,但不超过几KB。

我的建议:尝试使用尽可能少的分页或回溯进行就地处理。

答案 2 :(得分:1)

为什么不将它们组合在一起 - 使用cut来做最好的事情和ruby来提供胶水/值添加CUT的结果?您可以通过将它们放在这样的反引号中来运行shell脚本:

puts `cut somefile > foo.fil`
# process each line of the output from cut
f = File.new("foo.fil")
f.each{|line|
}

答案 3 :(得分:0)

我怀疑问题是ruby正在读取内存中的整个文件。在运行要验证的命令时查看内存和磁盘使用情况。

我猜主要的原因是因为cut是用C语言写的,只做了一件事,所以它可能被编译成非常金属的。它可能没有比调用系统调用做更多的事情。

然而ruby版本同时做了很多事情。调用方法在ruby中要比C函数调用慢得多。

记住老年人和trechery在unix中击败青年和技能:http://ridiculousfish.com/blog/archives/2006/05/30/old-age-and-treachery/