Cap'n Steve has asked for the wisdom of the Perl Monks concerning the following question:

Any light you can shed on these is appreciated.

1. I read somewhere that print statments are very slow, so I originally wanted to keep everything to one print at the very end. Would it be better to store all the variables globally or pass them to the subroutine that prints? (Let's just say we have 10-15 small variables or so.)

2. A little thing that's been bugging me: In a subroutine that takes parameters, is it faster to use shift() or $_[0]?

3. Normally, I use CGI.pm for my scripts, but it's a pretty large module and I'm concerned about speed since I only use it for reading cookies and submitted data. Would it be faster to just assign all the values to a hash at the beginning, and is there anything I might miss that CGI.pm would have caught?
  • Comment on Some questions about CGI and optimizing Perl

Replies are listed 'Best First'.
Re: Some questions about CGI and optimizing Perl
by gellyfish (Monsignor) on Aug 20, 2004 at 08:39 UTC

    You will hear many times something along the lines of "Premature optimization is evil" in the responses to this, and I think they will probably be right. The kind of micro-optimizations you are looking at are really not going to make a blind bit of difference unless your program is already running very quickly - if it is running slowly then these are not the places you want to be looking for, you may want to profile your code using something like Devel::DProf to see where the time is really being spent. Of course if you are only just starting out to write the program then I would worry more about getting it working than performance at this stage.

    If you are interested in the performance of individual Perl contructions then you can find this out yourself using the Benchmark module that comes with Perl.

    /J\

Re: Some questions about CGI and optimizing Perl
by weedom (Acolyte) on Aug 20, 2004 at 10:57 UTC

    1. if you're writing a daemon, or somesuch, then excessive screen output will slow it down tremendously. But in the world of CGI scripts, that's not a real issue. And anyway, it's not the print *function* which is slow, it's screen output in general.

    2. I would have thought that $_[0] would be marginally faster but again, for CGI purposes, it's not a real issue. Don't sweat the small stuff.

    3. Yes, it'll slow the compile down a bit. But I think it's worthwhile having, because of the work it saves you. Do you *really* want to write your own cookie-parsing routine??

    As someone else has already stated, I doubt strongly that any of these are actual problems for you if you're working in a CGI environment. Look elsewhere.. are you using a db, for instance? Having file-locking issues? Profile your code, see what gets run the most and streamline those bits.

Re: Some questions about CGI and optimizing Perl
by rupesh (Hermit) on Aug 20, 2004 at 09:42 UTC

    Have you tried whatever you've said above? I believe the best way to answer all your questions is to try them. I'm sure each one of us have faced your situation before, but that would be under differrent circumstances. All your questions are practical and it would defenitely be answered once you try to stimulate those problems.

    That being said, there are several ways of coding in perl to make the logic work faster. One way that you could time the responses to your code would be to use the benchmark module.
    Once you have done your "testing", please let us know also. All the best!
Re: Some questions about CGI and optimizing Perl
by Anonymous Monk on Aug 20, 2004 at 15:05 UTC
    3. Check out CGI::Minimal. It has both of those functions, and pretty much nothing else -- and it loads much faster than CGI.pm. -jc
      Err... oops :) CGI::Minimal doesn't cover cookies. Try CGI::Simple::Cookie (also) for that -- or perhaps just CGI::Simple. Either combo should be faster than straight CGI.pm; YMMV. -jc
        Thanks for the replies. I know I'm nitpicking, but I was curious. Obviously I want it to be readable, but it might as well be readable and fast, if possible. :)
Re: Some questions about CGI and optimizing Perl
by BUU (Prior) on Aug 20, 2004 at 21:19 UTC
    1. I read somewhere that print statments are very slow, so I originally wanted to keep everything to one print at the very end. Would it be better to store all the variables globally or pass them to the subroutine that prints? (Let's just say we have 10-15 small variables or so.)
    As other people have said further down, who cares? Printing isn't slow, compared to everything else you're doing in a CGI script. If you really want speed up, convert it to a mod_perl environment, and add a templating system like HTML::Template that can cache templates. Caches are extremely fast. Of course, if you want even faster you probably set up another server/apache process doing dedicated caching, but that's beyond the scope of this node.
    2. A little thing that's been bugging me: In a subroutine that takes parameters, is it faster to use shift() or $_0?
    This is silly to worry about. You should use shift so you can name your variables.
    3. Normally, I use CGI.pm for my scripts, but it's a pretty large module and I'm concerned about speed since I only use it for reading cookies and submitted data. Would it be faster to just assign all the values to a hash at the beginning, and is there anything I might miss that CGI.pm would have caught?
    This is actually a somewhat fair question, CGI.pm is horribly bloated and slow, but fortunately several alternatives, such as CGI::Simple, which is about twice as fast (I think), and CGI::Lite, which is even faster than CGI::Simple exist. There are benchmarks on this site if you really care.
Re: Some questions about CGI and optimizing Perl
by amt (Monk) on Aug 20, 2004 at 14:17 UTC
    1. If you are looking to print in a web-based situation, it is best that you use print <<EOM; If you know this, then disregard the rest, but it allows you to print out until the intepreter finds that specific string. Very convenient, especially if you are printing at the end of your script. Passing variables is always preferable to using globals, just from the aspect of good programming practice.

    2. I think that using built in reserved oeprators are faster than calling shift, but calling shift explicitly gives you the variable, where $_ may occasionally get you mixed up, and that's alot harder to find, especially when Apache is barking at you ;)

    3. If you are concerned about speed, then you should consider compiling Apache with mod_perl, but CGI.pm is a great interface, and makes life alot easier. You don't need to concern yourself with the HTTP header information, but if you want to make the most of the module, you can consider using it to output your resulting HTML using that module. So you don't need to learn that terrible markup language ;)

    amt
Re: Some questions about CGI and optimizing Perl
by Anonymous Monk on Aug 20, 2004 at 14:20 UTC
    on #2:

    using @_ might be faster, but you'll probably find that it's much easier to keep your paramater order in line by using shift. It also allows you to set up defaults, and avoid warnings about using undefined parameters. Consider

    $x = shift || 4; $p = shift || 'happy'; $q = shift || return 0;

    Using @_ , you'll probably end up by checking if it is defined - which is a bit more messy looking IMHO

      One problem:

      $x = shift || 4;

      What happens if you really want to pass 0 in? It just won't work. So you still end up with a defined test (or apply the "defined or" patch):

      $x = shift; $x = defined $x ? $x : 4; # Or with the "defined or" patch $x = shift // 4; # Or check if there is anything left on @_ and shift if there is $x = @_ ? shift : 4;

      "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.