Error.pm のオーバーヘッド

Error モジュールが例外処理を書くのに便利そうだなと思って、採用する前にオーバーヘッドがどれくらいあるのかと思い調べてみました。

ベンチマークコード

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

cmpthese(timethese(100000, {
    'eval' => sub {
        _eval(\&die_with_object);
        _eval(\&die_with_string);
        _eval(\&dont_die);
    },
    'try'  => sub {
        _try(\&die_with_object);
        _try(\&die_with_string);
        _try(\&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 _try {
    my $code = shift;
    my $res;
    try {
        $res = $code->();
    }
    catch Error::Simple with {
        $res = shift->stacktrace;
    }
    otherwise {
        $res = shift;
    };
    return $res;
}

ベンチマーク結果

Benchmark: timing 100000 iterations of eval, try...
      eval:  6 wallclock secs ( 0.01 usr +  5.41 sys =  5.42 CPU) @ 18450.18/s (n=100000)
       try: 23 wallclock secs ( 0.12 usr + 22.68 sys = 22.80 CPU) @ 4385.96/s (n=100000)
        Rate  try eval
try   4386/s   -- -76%
eval 18450/s 321%   --

結論

タイプ量が格段に減るわけでも無いし、オーバーヘッドを考えると、今まで通り eval と if 文で良いかなと思いました。