ファイルの読み込み
いや、これ benchmark になってないから。試しにこんなのを書いて実行してみると分かる。
use strict; use warnings; print join('', <DATA>); print do { local $/; <DATA> }; __DATA__ sample program for reading __DATA__.
1行しか出力されないはず。__DATA__ 以下のデータを複数回読みたい場合には初期位置を記憶しておいて seek しないといけない。(さて、seek DATA, 0, 0 だとどうなるでしょう?)
use strict; use warnings; my $pos = tell DATA; print join('', <DATA>); seek DATA, $pos, 0; print do { local $/; <DATA> }; __DATA__ sample program for reading __DATA__.
どうせなので、File::Slurp と Perl6::Slurp を入れて benchmark。
プログラム自身を読み込ませる。
% perl slurp.pl Benchmark: running File::Slurp, Perl6::Slurp, join, sep for at least 3 CPU seconds... File::Slurp: 2 wallclock secs ( 2.26 usr + 0.74 sys = 3.00 CPU) @ 39327.00/s (n=117981) Perl6::Slurp: 3 wallclock secs ( 2.56 usr + 0.51 sys = 3.07 CPU) @ 25072.96/s (n=76974) join: 3 wallclock secs ( 2.69 usr + 0.51 sys = 3.20 CPU) @ 28350.00/s (n=90720) sep: 3 wallclock secs ( 2.13 usr + 1.05 sys = 3.18 CPU) @ 56802.20/s (n=180631) Rate Perl6::Slurp join File::Slurp sep Perl6::Slurp 25073/s -- -12% -36% -56% join 28350/s 13% -- -28% -50% File::Slurp 39327/s 57% 39% -- -31% sep 56802/s 127% 100% 44% --
zsh のヒストリを読ませてみる。
% perl slurp.pl ~/.zsh-history Benchmark: running File::Slurp, Perl6::Slurp, join, sep for at least 3 CPU seconds... File::Slurp: 3 wallclock secs ( 1.55 usr + 1.56 sys = 3.11 CPU) @ 104.18/s (n=324) Perl6::Slurp: 3 wallclock secs ( 2.63 usr + 0.56 sys = 3.19 CPU) @ 72.10/s (n=230) join: 3 wallclock secs ( 2.90 usr + 0.17 sys = 3.07 CPU) @ 12.70/s (n=39) sep: 3 wallclock secs ( 2.43 usr + 0.86 sys = 3.29 CPU) @ 107.60/s (n=354) Rate join Perl6::Slurp File::Slurp sep join 12.7/s -- -82% -88% -88% Perl6::Slurp 72.1/s 468% -- -31% -33% File::Slurp 104/s 720% 44% -- -3% sep 108/s 747% 49% 3% --
む。Perl6::Slurp のパフォーマンスが思ったほど良くないな。まぁ、どちらにしても join を使うのはやめておけと。
あと、File::Slurp のアーカイブには extras/slurp_bench.pl というスクリプトがついてきているのでこれを試してみるのも面白いかも。
use strict; use warnings; use utf8; use Perl6::Slurp qw(slurp); use File::Slurp; use Benchmark qw(cmpthese timethese); my $filename = shift @ARGV || $0; cmpthese( timethese( 0, { 'join' => sub { open my $fp, '<', $filename or die; my $text = join('', <$fp>); close $fp; }, 'sep' => sub { open my $fp, '<', $filename or die; my $text = do { local $/; <$fp> }; close $fp; }, 'Perl6::Slurp' => sub { my $text = slurp '<', $filename; }, 'File::Slurp' => sub { my $text = read_file $filename; }, } ) );