如何快速对大型数据文件进行切片和切块?
时间: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| }