如何快速对大型数据文件进行切片和切块?

时间:2020-03-06 14:37:46  来源:igfitidea点击:

我想以相当快速和有效的方式将大型数据文件切片和切成小块,直到一个演出。如果我使用UNIX的" CUT"之类的东西,即使在CYGWIN环境中,它也非常快。

我尝试开发各种Ruby脚本并对其进行基准测试以处理这些文件,并且始终以令人反感的结果结束。

我们将在Ruby中做些什么,以使其不至于太慢?

解决方案

这个问题使我想起了Tim Bray的Wide Finder项目。他使用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
   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
It took this code 7? seconds of CPU, 13? seconds elapsed, to process a million and change records, a quarter-gig or so, on last year’s 1.67Ghz PowerBook.

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

我的建议:尝试就地进行处理,并尽可能减少分页或者回溯。

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

我想主要原因是因为cut是用C编写的,并且只做一件事,因此它可能已被编译为非常简单的东西。除了调用系统调用外,它所做的可能不多。

但是,红宝石版本可以一次完成很多事情。在Ruby中,调用方法比C函数调用要慢得多。

记得在Unix中,年纪大和战胜了年轻人和技能:http://ridiculousfish.com/blog/archives/2006/05/30/old-age-and-treachery/

为什么不使用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|
}