例外捕捉モジュール Try::Tiny のベンチマーク

Yuval Kogman 氏が Try::Tiny という新しい例外捕捉モジュールをリリースしたようなので、ベンチマークを取ってみました。

ベンチマークコードは、Error.pm のオーバーヘッドで書いたものを流用しました。

ベンチマークコード

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw(:all);
use Try::Tiny;
use Error;

cmpthese(timethese(100000, {
    'eval' => sub {
        _eval(\&die_with_object);
        _eval(\&die_with_string);
        _eval(\&dont_die);
    },
    'try'  => sub {
        _tiny(\&die_with_object);
        _tiny(\&die_with_string);
        _tiny(\&dont_die);
    },
}));

sub die_with_object {
    Error::Simple->throw('object');
}

sub die_with_string {
    die 'string';
}

sub dont_die {
    return "still alive\n";
}

sub _eval {
    my $code = shift;
    my $res;
    eval {
        $res = $code->();
    };
    if (ref $@ eq 'Error::Simple') {
        $res = $@->stacktrace;
    }
    elsif ($@) {
        $res = $@;
    }
    return $res;
}


sub _tiny {
    my $code = shift;
    my $res;
    try {
        $res = $code->();
    }
    catch {
        if (ref $@ eq 'Error::Simple') {
            $res = $@->stacktrace;
        }
        elsif ($@) {
            $res = $@;
        }
    };
    return $res;
}

ベンチマーク結果

Benchmark: timing 100000 iterations of eval, try...
      eval: 11 wallclock secs (10.52 usr +  0.00 sys = 10.52 CPU) @ 9505.70/s (n=100000)
       try: 19 wallclock secs (18.57 usr +  0.01 sys = 18.58 CPU) @ 5382.13/s (n=100000)
       Rate  try eval
try  5382/s   -- -43%
eval 9506/s  77%   --

結論

Error より速いですが、オブジェクトごとに with で補足したりはできないので、やはり eval と if で良い気がします。