これってどっちが早いんだろう
ふと考えてみたんだけど
あるファイル(以下A)から特定の値(以下X)が入っている行だけ抽出して、その結果を処理したい、という時はどっちが早いのか。どっちも大差ないものなんだろうか。
※ただし、プログラムは Ruby から起動しなくてはいけないものとする
- Ruby からキックされ、systemメソッド(システムコール)でAから grep で抜き出した結果をファイルへ出力。その結果のファイルを Ruby で読み込む
- Ruby で A を読み込み、 if 文で該当行だけ抜き出して、必要な行のみ取得する。
これってどっちが早いんだろうね。ネイティブなコマンドを使ってる分、1. の方がはやそうだけど、処理のスマートさで行ったら 2. だよね*1。
というわけで、実験してみる。
こんなデータでやってみたよ
2000/12/16,Hirai Ken,8th,why
2000/5/10,Hirai Ken,9th,LOVE OR LUST
2000/1/19,Hirai Ken,10th,even if
2000/12/16,Hirai Ken,8th,why
2000/5/10,Hirai Ken,9th,LOVE OR LUST
2000/1/19,Hirai Ken,10th,even if
:
こんな感じの3つのデータが繰り返し現れる CSV ファイルを用意した。
これを合計1万行まで繰り返したのが A というファイル。
1万行のデータから 'even if' の含まれている行を調べてして、何行抽出されたかを出力する。
なるべく差のでないようなソースを心がけてみたのだけど……どうだろうか。
検証ソース:システムコールを使う版
FILE_NAME='Book1.csv' TEMP_FILE='system.tmp' system("grep 'even if' #{FILE_NAME} > #{TEMP_FILE}") File.open(TEMP_FILE, 'r') do |file| puts file.readlines.size end
検証ソース:Rubyだけで処理する版
FILE_NAME='Book1.csv' list=[] File.open(FILE_NAME, 'r') do |file| file.each do |line| list << line if line =~ /even if/ end end puts list.size
実験結果
[masa@www]~/sokutei% time ruby ./system.rb
33320
ruby ./system.rb 0.06s user 0.03s system 99% cpu 0.091 total
[masa@www]~/sokutei% time ruby ./ruby_onry.rb
33320
ruby ./ruby_onry.rb 0.37s user 0.12s system 97% cpu 0.509 total
どうみてもシステムコールの方が早いです。当たり前です。本当にありがとうございました。
システムコールで実装した方は中間ファイルを吐くので、その分で差が出てくるかと思ったら全然そんなことなかった_| ̄|○
続き
こっちにかいたよー
http://d.hatena.ne.jp/seiunsky/20071107/1194448571