ファイルの読み込み

いや、これ 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;
            },
        }
    )
);