http://www.perlmonks.org?node_id=629736


in reply to Re: Nested evals - are they evil? (sample benchmarks)
in thread Nested evals - are they evil?

Exceptions should be "exceptional". That is, you shouldn't expect them to happen during normal functioning of the program. So lets see what the overhead of providing (unused) exception handling is:

use strict; use warnings; use Benchmark 'cmpthese'; cmpthese(-1, { 'eval' => \&eval_code, 'noeval' => \&no_eval_code, }); sub eval_code { my $x = 0; for (reverse 0..9) { eval { some_more_code ($_); }; if ($@) { error_sub(); } } } sub no_eval_code { for (reverse 0..9) { if ($_==0) { error_sub(); } else { some_more_code ($_); } } } sub some_more_code { } sub error_sub { }

Prints:

Rate eval noeval eval 185563/s -- -7% noeval 198639/s 7% --

In words: the processing cost of an unexercised eval is essentially nothing.


DWIM is Perl's answer to Gödel

Replies are listed 'Best First'.
Re^3: Nested evals - are they evil? (sample benchmarks)
by cLive ;-) (Prior) on Jul 31, 2007 at 07:05 UTC
    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 :)