2013/03/10

Benchmark に食わせてるルーチンの返り値が同じかチェックしたい

perl において、ルーチンを比較するためのデファクトスタンダードといえば Benchmark モジュールなわけですが、いろいろとルーチンを比較していると、うっかり異なる結果になってしまっていて、速いとか遅いの問題じゃなくなってるよ時間返せ! みたいなことになったりしませんか? ぼくはありません。ええ、ありません。

まあ、でも、きっちりそれを確認するのに時間割いてるとしたら地味に無駄ですよね。

というわけで、パッチ書いてみました。Benchmark 1.11 へのパッチです。

440c440
<             clearcache clearallcache disablecache enablecache);
---
>             clearcache clearallcache disablecache enablecache checkreturn);
471c471
<     %_Usage, %Cache, $Do_Cache);
---
>     %_Usage, %Cache, $Do_Cache, $Check_Return, $Return_Value);
478a479
>     $Check_Return = 0;
532a534
> sub checkreturn { $Check_Return = ($_[1] != 0); }
643a646
>     my $checkref;
646a650,652
>         if ($Check_Return) {
>             $checkref = eval "sub { local \$_; package $pack; &\$c; }";
>         }
650a657,659
>         if ($Check_Return) {
>             $checkref = _doeval("sub { local \$_; package $pack; $c; }");
>         }
654a664,672
>     if ($Check_Return) {
>         my $retval = $checkref->();
>         $Return_Value = $retval unless defined $Return_Value;
>         if ( defined $Return_Value && defined $retval
>                 && $Return_Value ne $retval ) {
>             croak "return values are wrong $Return_Value from '$c' : $retval" ;
>         }
>     }
>

$Benchmark::Check_Return=1 するか Benchmark->checkreturn(1) しておけば、ルーチンの返り値がそれぞれ異なる場合に croak するようになります。

まあ、取り急ぎ晒してみる。

全体像はこちらの gist に貼りました。

サイト内検索