Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

How to store CODE ref

by gildir (Pilgrim)
on Nov 28, 2001 at 21:55 UTC ( [id://128112]=perlquestion: print w/replies, xml ) Need Help??

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

Fellow monks,

I have piece of perl code. I want to pre compile it, and store it in some kind of permanent storage for subsequent fast execution. I can compile code to coderef simply by $code = eval "sub { $code }"; bu how I store and restore such a code?

Yes, yes, I know that Perl is portable only in string source form. I know that this may cause problems. But I need it for short-term optimazation only, in Web server. Just to avoid compiling pieces of ebmede Perl code again and again.

I think that there is some module that can store pre-compiled perl code to file. That should be sufficient, but I just can't find that module on CPAN anymore. Could anyone help me, please.

Replies are listed 'Best First'.
Re: How to store CODE ref
by tachyon (Chancellor) on Nov 28, 2001 at 22:04 UTC

    If efficiency is the aim surely modperl and putting the code in a module would be a good choice. Once the module is loaded and the code compiled it is ready, willing and able for the duration. Often the major bottleneck is in the overhead of starting the new process for each request, not compiling the actual Perl code itself. Under modperl you start one process, compile once and then use this process to deal with all subsequent requests. The first one is slow then it is Win Win Win.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Hmmm, maybe I did not made myself perfectly clean. I do use mod_perl just now, but it has several drawbacks. One such drawback is described in Fast shared data structures.

      In short, the problem is with large, mostly-read data that contains embeded perl code. For example, ePerl templates. For efficiecy reasons they must be pre-compiled. That's perfectly easy so far. But I want to change the templates while server is running. No chance to do this efficiently in Apache one-process-per-request architecture.

      So I come up with an idea to store templates in GDBM. But what about embeded perl here? If I whould store it in source form, it will be terribly slooow, compile it in every HTTP request. If I compile it in every httpd process, it will be terribly large. Now, I must pre-compile perl code and store it in GDBM in pre-compiled form.

      How to do that?

      Ad B::Bytecode. I have checked this module, and it looks good. But I can't fugure out how to use it no a piece of perl source that I have in scalar variable instead of whole perl program. Could anyone please help me with this. Some simple 3-line example would be more that sufficient. Thanks a lot.

        You can store your templates in some file cache or database in source form. On each requiest you should check if cache have been updated (just check timestamp of relevant files). If it have been updated you need to recompile template from cache. If it haven't been updated you can use already compiled templates. This is how HTML::Mason handles its components (as example).
Re: How to store CODE ref
by Fletch (Bishop) on Nov 28, 2001 at 22:20 UTC

    Simple answer is go with mod_perl as mentioned before.

    Longer answer: This is pretty much completely untested, but you could overload strigification and use a tied scalar which keeps the coderef and the original code together. Then you can do something sort of like:

    tie $somecode, CodeNRef => qq{print "This is my code\n"}; $somecode->( ); print tied $somecode;

    Where the hypthetical CodeNRef package would look something like:

    package CodeNRef; use overload q{""} => \&print_code; sub TIESCALAR { my( $class, $code ) = @_; my $ref = eval qq{ sub { $code } }; return bless { code => $code, compiled => $ref }, $class; } sub print_code { shift()->{code} } sub FETCH { my $self = shift; return $self->{compiled} } 1;

    Update: Feh, who needs to play around with tie'd stuff. Just overload &{}.

    package CodeNRef; use overload q{""} => \&print_code, q{&{}} => \&call; sub new { my( $class, $code ) = @_; my $ref = eval qq{ sub { $code } }; return bless { code => $code, compiled => $ref }, $class; } sub print_code { shift()->{code} } sub call { shift()->{compiled} } 1;
Re: How to store CODE ref
by IlyaM (Parson) on Nov 28, 2001 at 22:19 UTC
    New Perls can generate bytecode of scripts. Read documentation for module B::Bytecode. It relies on experimental support for Perl compilers so it can be unstable. Moreover I've heard that actually it doesn't give any perfomance boost and is actually slower. But don't trust me :) Check yourself.

    However if you just want to optimize your code for web server probably you should use mod_perl. It allows to read all your code once on startup of web server so Perl code is not complied again and again.

Re: How to store CODE ref
by perrin (Chancellor) on Nov 28, 2001 at 22:18 UTC
    I believe this was tried with the bytecode loader and gave no significant performance improvement. You should try to use one of the many systems that lets you load perl code once and keep it in memory, like mod_perl, FastCGI, SpeedyCGI, PerlEx, Velocigen, etc.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://128112]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-19 05:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found