これってどっちが早いんだろう - すがブロ で
「system関数から実行したgrepコマンドの方が、ruby内でパターンマッチするより早い」的なことが書いてあって、しかもそれは「当たり前」のことらしい。個人的な感覚としては、外部プロセス呼び出すオーバーヘッドの方が明らかに大きいだろうと思ってたのでかなり衝撃だった。のでPerlで試してみよう。
use strict; use warnings; use Benchmark qw(timethese cmpthese); my $file = 'Book1.csv'; my $tmpfile = 'tmp.out'; cmpthese(timethese(100, { native_grep => sub{ system("grep 'even if' $file > $tmpfile"); open(F, $tmpfile); print STDERR while (<F>); close(F); }, pureperl_grep => sub{ open(F, $tmpfile); while(<F>){ print STDERR if /even if/; } close(F); } }));
できた。perl v5.8.8 built for cygwin-thread-multi-64intでの実行結果
$ perl grep.pl 2>/dev/null Benchmark: timing 100 iterations of native_grep, pureperl_grep... native_grep: 53 wallclock secs ( 2.08 usr 5.64 sys + 10.01 cusr 17.78 csys = 35.51 CPU) @ 12.96/s (n=100) pureperl_grep: 8 wallclock secs ( 2.09 usr + 4.78 sys = 6.87 CPU) @ 14.55/s (n=100) Rate native_grep pureperl_grep native_grep 13.0/s -- -11% pureperl_grep 14.5/s 12% --
Pure Perlの方が早いよなあ・・・。Cygwinだからかと思って、某OS*1でも実行してみた。
# perl grep.pl 2>/dev/null Benchmark: timing 100 iterations of native_grep, pureperl_grep... native_grep: 5 wallclock secs ( 1.49 usr 0.98 sys + 0.90 cusr 0.70 csys = 4.07 CPU) @ 40.49/s (n=100) pureperl_grep: 3 wallclock secs ( 1.88 usr + 0.86 sys = 2.74 CPU) @ 36.50/s (n=100) Rate pureperl_grep native_grep pureperl_grep 36.5/s -- -10% native_grep 40.5/s 11% --
やっぱりPure Perlの方が・・・と思ったら逆になった。Cygwinのオーバーヘッドなのか・・・。
プロファイルも取ってみたけど、unknownな情報が多い上にblogに書けないことが多すぎるからあまり深追いはしないでおこう。Cygwinでプロファイルって取れるんだろうか・・・