Hmmm, well, I stripped it down further:
use strict;
use warnings;
use Benchmark 'cmpthese';
cmpthese(-1, {
'eval' => \&eval_code,
'noeval' => \&no_eval_code,
});
sub eval_code {
eval {
some_more_code ();
};
if ($@) {
error_sub();
}
}
sub no_eval_code {
if (0) {
error_sub();
}
else {
some_more_code ();
}
}
sub some_more_code { }
sub error_sub { }
And got this (I think the effectively empty eval is meaningless - see here where I ran it 4 times):
Rate eval noeval
eval 1298354/s -- -37%
noeval 2066450/s 59% --
Rate eval noeval
eval 1316991/s -- -38%
noeval 2123851/s 61% --
Rate eval noeval
eval 1217925/s -- -21%
noeval 1534287/s 26% --
Rate eval noeval
eval 1298354/s -- -41%
noeval 2205537/s 70% --
I have a feeling an empty eval gets optimized away at compile time (though I am most probably wrong :)
How about if I add in an increment do ensure each eval has to be 'eval'd, ie
use strict;
use warnings;
use Benchmark 'cmpthese';
my $x;
cmpthese(-1, {
'eval' => \&eval_code,
'noeval' => \&no_eval_code,
});
sub eval_code {
$x=1;
eval {
some_more_code ();
};
if ($@) {
error_sub();
}
}
sub no_eval_code {
if ($x==0) {
error_sub();
}
else {
$x=0;
some_more_code ();
}
}
sub some_more_code { $x++ }
sub error_sub { }
I get this:
Rate eval noeval
eval 989400/s -- -23%
noeval 1286220/s 30% --
-bash-3.00$ perl tmp.pl
Rate eval noeval
eval 1092266/s -- -21%
noeval 1379705/s 26% --
Rate eval noeval
eval 1069351/s -- -19%
noeval 1327443/s 24% --
Rate eval noeval
eval 1071850/s -- -25%
noeval 1435550/s 34% --
Rate eval noeval
eval 1071850/s -- -26%
noeval 1456355/s 36% --
Either way, I still haven't been able to create a counter example that shows eval to be faster.
But anyway, considering the number of runs a second, I have a feeling my energies are probably better spent focusing on other parts of the code as far as optimizations are concerned :)