[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: compiling perl scripts



Kevin Krafthefer <krafty@telocity.com> wrote:
>I am trying to speed up a perl script. So I am trying to byte compile
>it, however, the resulting "c" code (from perl -MO script.pl) has some
>header files that I don't have (EXTERN.h, perl.h, patchlevel.h, and
>cc_runtime.h).

Try compiling with -I/usr/lib/perl5/5.005/i386-linux/CORE.

>Any ideas what packages might have these? Or any general pointers in
>general on byte compiling perl?

To be honest: don't bother. You end up with an enormous executable
unless you have a libperl.so, and even then you have to assume people
you're distributing it to have that library too. If you compile, evals
get noticeably hairier. And it's harder to debug.

Also, you should understand that the speed gains are relatively small.
Compiling speeds up the loading process, of course, but after that the
script will (as far as I know) run at the same speed. Even the loading
process isn't all that slow. As a data point, some benchmarks done by
people at the web server company I work for compared CGIs written in C
and Perl against various other forms of dynamic content generation, and
while the difference was there it wasn't anything to worry about (a
fraction of the difference between CGI and FastCGI, for example).

If you want to speed up your Perl scripts, there are much more useful
things you can do:

  * Don't 'use diagnostics' in production code. It slows down compiling
    by about a third of a second to half a second of a few-hundred-line
    script on this P3-450.

  * Check your use of other modules to make sure you aren't sucking in
    large volumes of general-purpose code. For instance, using the
    Exporter might be overkill if you just want to export one symbol, as
    you could manipulate the symbol table yourself, or using IO::File
    might be overkill if all you want is localized filehandles, as you
    can do that with 'local *FH'.

  * Use the /o switch on regexes containing variable interpolation if
    you're sure the variables won't change over the lifetime of the
    script. Or, if they will change but not within some inner loop, wrap
    that loop in an eval().

  * study() scalars on which you're going to do a lot of pattern
    matches.

  * Use Perlish constructs where you can. For instance, 'foreach my
    $element (@list)' is faster than 'for (my $i = 0; my $element =
    $list[$i]; $i++)'.

  * Generally, the fewer operators you use, the faster your code will
    be.

  * Watch out for list assignments, passing large argument lists into
    functions, and returning large lists from functions, all of which
    can lead to a lot of data being copied around unnecessarily. Use
    references instead if the lists are large.

  * Use techniques like the Schwartzian Transform or the Guttman-Rosler
    Transform when sorting large lists on only part of each element.

  * Cache the results of frequently called functions. The Memoize module
    on CPAN may help with this.

  * Don't use functions that invoke shells if you can possibly avoid it,
    for reasons of both security and speed.

  * ... and, of course, the usual "check your algorithms", as you would
    for any language.

Hope that helps,

-- 
Colin Watson                                     [cjw44@flatline.org.uk]



Reply to: