さらば IO::Scalar

  • 投稿日:
  • by
  • カテゴリ:

今まで Perl で変数の中身をファイルとして扱うときは IO::Scalar を使ってたんですが、Perl 5.8.0 から open に変数のリファレンスをそのまま渡せば同じことができることを最近知りました。
普通に perldoc -f open に書いてあった。

つまり、

use IO::Scalar;

my $buf = '';
my $out = IO::Scalar->new(\$buf);
print {$out} "Num $_\n" for 1..10;

みたいなことが、

use 5.8.0;

my $buf = '';
open my $out, '>', \$buf or die $!;
print {$out} "Num $_\n" for 1..10;
close $out;

こう書けるってことで。
なんということだ。こっちのほうがずっとシンプルじゃないか。

ビルトインの open 使うほうが効率も良さそうだったのでベンチを取ってみることにした。

#!/usr/bin/perl

use strict;
use warnings;

use IO::Scalar;
use Benchmark qw(timethese cmpthese);

my @data = map { int rand 1000 } 1..1000;

cmpthese(
    timethese(10000, {
        IO_Scalar => \&with_io_scalar,
        PerlIO    => \&with_perl_io,
    })
);

sub with_io_scalar {
    my $output;
    my $ios = IO::Scalar->new(\$output);
    local *STDOUT = $ios;
    print $_ for @data;
}

sub with_perl_io {
    my $output = '';
    open my $ios, '>', \$output or die $!;
    local *STDOUT = $ios;
    print $_ for @data;
    close $ios;
}

これを実行させたところ、

Benchmark: timing 10000 iterations of IO_Scalar, PerlIO...
 IO_Scalar: 43 wallclock secs (42.33 usr +  0.00 sys = 42.33 CPU) @ 236.25/s (n=10000)
    PerlIO:  3 wallclock secs ( 2.47 usr +  0.00 sys =  2.47 CPU) @ 4050.63/s (n=10000)
            Rate IO_Scalar    PerlIO
IO_Scalar  236/s        --      -94%
PerlIO    4051/s     1615%        --

ちょwwwwww違いすぎじゃねwwwwwwwwwww