大きなデータファイルを素早くスライスしてサイジングするにはどうすればよいですか?


5

大規模なデータファイルを非常に素早く効率的にスライスしてサイコロにしたいと思っています。 UNIXの「CUT」のようなものを使用すると、CYGWIN環境でも非常に高速です。

私はこれらのファイルを処理するためにさまざまなRubyスクリプトの開発とベンチマークを試みましたが、常に氷の結果に終わりました。

これを犬ほど遅くしないためにRubyで何をしますか?

1

はなぜそれらを互いに結合していない - それはCUTからの結果と追加の接着剤/価値を提供するのが最善とルビー何を行うにカット使用して?あなたは、このようなバッククォートでそれらを置くことによってシェルスクリプトを実行することができます。

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

ではなく、一時ファイルへの書き込み、あなたが行う可能性があります:パイプ= IO.popen(「カット...」); pipe.each_line {| line | ...} 29 7月. 092009-07-29 16:22:34


2

この質問はTim Brayの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 
それは、このコードCPUの7½秒かかった

は、13½秒経過します昨年の1.67Ghz PowerBookには百万分の一、変更記録、四分の一ギグかそうだった。


1

あなたのRuby実装は、処理前にファイル全体を読み込んでいると思います。 Unixのカットは一度に1バイトずつ読み込み、すぐに出力ファイルにダンプします。もちろん、いくつかのバッファリングが含まれていますが、数KB以下です。

私の提案:できるだけ小さなページングまたはバックトラッキングでインプレース処理を実行してみてください。


0

私は、rubyがメモリ内のファイル全体を読み込んでいることに問題はないと考えています。検証するコマンドを実行している間、メモリとディスクの使用状況を確認してください。

私は主にカットがCで書かれているだけなので、それはおそらく非常に金属にコンパイルされていると思います。おそらく、システムコールを呼び出すよりはるかに多くはありません。

しかし、ルビーバージョンはすぐに多くのことをやっています。メソッドの呼び出しは、C関数の呼び出しよりもはるかに遅いです。

は、UNIXで若者とスキルを破っ古い時代とtrecheryを忘れないでください:http://ridiculousfish.com/blog/archives/2006/05/30/old-age-and-treachery/