PetaMem has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

in an ultra-lightweight webserver I have this code:

sub loadCode { my $this = shift; my $scrref = &getFileAsString($this->{filename}); # load into the re +gistry $this->{code} = sub {eval($$scrref);}; # store the script in a +n anonymous subroutine }

The code is then executed as &{$this->{code}};. This works - to a certain extent - well. As already stated in the camel book, the eval EXPR is much slower than the eval BLOCK syntax. And if I do cut&paste code and do a BLOCK after eval (resulting in sub {eval { <verbatim perl-code here...> }; }, execution gets about 18times faster.

My problem is simple: I'm greedy ;-) - that is - I would like to benefit from the speedup, but also be able to initialize these anonymous subroutines at startup of the script (they do not need to be changed at runtime).

I thought about constructing perl source code by another script, but before I'd do such a kludgy solution, I wanted to ask you if there is not a better solution. All in all: mod_perl must do something similar - no?

Thank you for your suggestions.

Bye
 PetaMem
    All Perl:   MT, NLP, NLU

Replies are listed 'Best First'.
Re: eval BLOCK with runtime-loaded code?
by Corion (Patriarch) on Jul 22, 2005 at 13:07 UTC

    A simple change should help you:

    Change

    sub { eval $$scrref };

    into

    eval "sub { $$scrref }";

    That way, the eval only happens once.

      but don't forget that:

      "... no matter how many times you execute that particular line (unless you're in an eval("...")), $coderef will still have a reference to the same anonymous subroutine."

      as quoted in this link under perldoc.
Re: eval BLOCK with runtime-loaded code?
by chromatic (Archbishop) on Jul 22, 2005 at 16:53 UTC
    I would like to benefit from the speedup, but also be able to initialize these anonymous subroutines at startup of the script...

    Sort of like modules?

      Sort of like modules?

      No. Sort of like persistent cgi scripts. Corions answer was exactly what I was looking for. It gave a speedup of 22!

      Bye
       PetaMem
          All Perl:   MT, NLP, NLU

Re: eval BLOCK with runtime-loaded code?
by wazoox (Prior) on Jul 22, 2005 at 13:29 UTC
    Perhaps you may modify slightly your dynamically-read code and use "do" instead of "eval"? It's supposed to be faster.