in reply to Re: Why can code be so slow?
in thread Why can code be so slow?

CGI.pm, by itself, is around 237K bytes of code - and it pulls in Carp (8 Kbytes in perl 5.8.8). Carp then pulls in Exporter (15 Kbytes), Exporter pulls in Exporter::Heavy (6 Kbytes) and Exporter::Heavy pulls in strict (3 Kbytes). If you do a 'use warnings;' that pulls another 16 Kbytes. If you do 'use CGI::Carp;' that will tack on another 16 Kbytes.

I shouldn't have to say, yet again, that CGI.pm uses a self-loading scheme to avoid compiling everything, so the way you load it makes a tremendous difference.

I will say that in this type of microbenchmark, the contents of @INC and the location of modules in @INC can have a tremendous difference. Perl startup speed can depend greatly on the number of stat calls.

Replies are listed 'Best First'.
Re^3: Why can code be so slow?
by snowhare (Friar) on May 01, 2007 at 19:23 UTC
    True - and irrelevant except to the extent of being able to say "it would be even worse than it is actually measured performance-wise if it didn't do that." The test script for CGI.pm consisted of this:
    #!/usr/bin/perl use CGI; my $cgi = CGI->new; my $value = $cgi->param('a'); print "Content-Type: text/plain\015\012\015\012a=$value\n";
    Note that I do *NOTHING* not necessary for the script to execute. If you can suggest a faster way than to use CGI.pm in a script than that, I would be fascinated to know what it is.
      True - and irrelevant...

      It's extremely relevant, if Perl doesn't actually compile all of that code. If your point was that Perl has to find and read all of those blocks from disk, that's fine. I didn't get that impression from your notes, however.

      If you can suggest a faster way than to use CGI.pm in a script than that, I would be fascinated to know what it is.

      Make sure CGI.pm is in the first directory in @INC.

      To do this benchmark properly, make sure all of the modules you want to load are in the same directory, and preferably the first directory in @INC. If you really want to compare the weight of one module over another, you have to remove all other variations, and disk IO can be a very large variation, especially if compilation and execution time is minimal as in this case.

        Fine. For your edification.

        speedtest-cgi-minimal.pl

        #!/usr/bin/perl use CGI::Minimal; my $value = CGI::Minimal->new->param('a'); print "Status: 200 OK\015\012Content-Type: text/plain\015\012\015\012a + = $value\n";

        speedtest-cgi-pm.pl

        #!/usr/bin/perl use CGI; my $value = CGI->new->param('a'); print "Status: 200 OK\015\012Content-Type: text/plain\015\012\015\012a + = $value\n";

        I ran the test both with them hardlinked from the first @INC directory and then again with them in only their normal locations. The test was a 60 second run with 30 parallel fetches of http_load of each on a P4 with hyperthreading enabled at 3.06 GHz (I used a second fast machine to execute http_load for the requests). The version of Apache was 2.2.2 and the version of Perl was 5.8.8.

        in first @INC Directory Normal CGI.pm (3.25) 21.5/second 21.5/second CGI::Minimal (1.26) 73.8/second 73.6/second

        The difference is below the system noise floor. Any other criticisms of my methodology?

        My 'irrelevant' statement point was that it doesn't really matter a whole lot that if CGI.pm didn't do its clever little trick with subroutines stored in hash strings that it would be even slower than it is right now. It still is measured to run much slower than any of the alternative CGI parameter processing modules and that difference is simply due to its raw size.

      This makes me wonder if I better keep using my own routines to get my parameters etc instead of using CPAN modules. Do these modules take their entire size as overhead or only the subroutines which get executed? I've also noticed a few weird things with a package I've made slurping more CPU (and memory) than it should take; I only use XML::Twig and XML::Simple in that package (for backwards compatibility for now)

      Visual::XML::BEGIN is which I really wonder about ; only 3 calls and 17.5 time for executing these; while its merely a package of 3 routines made as proxy to be backwards compatible using XML::Twig with XML::Simple calls...

      %Time ExclSec CumulS #Calls sec/call Csec/c  Name
       42.0   0.120  0.188     16   0.0075 0.0118  Visual::XML::Podcast::BEGIN
       17.5   0.050  0.278     10   0.0050 0.0278  main::BEGIN
       17.5   0.050  0.060      3   0.0166 0.0199  Visual::XML::BEGIN
       3.50   0.010  0.010     47   0.0002 0.0002  strict::bits
       3.50   0.010  0.010      1   0.0100 0.0100  utf8::AUTOLOAD
       3.50   0.010  0.010     29   0.0003 0.0003  XML::Twig::BEGIN
       3.50   0.010  0.010      3   0.0033 0.0033  LWP::Simple::BEGIN
       3.50   0.010  0.010      1   0.0100 0.0100  Visual::XML::Podcast::itunes::BEGIN
       3.50   0.010  0.010      7   0.0014 0.0014  IO::File::BEGIN
       0.00   0.000 -0.000     31   0.0000      -  strict::import
       0.00   0.000 -0.000      1   0.0000      -  vars::BEGIN
       0.00   0.000 -0.000      1   0.0000      -  warnings::BEGIN
       0.00   0.000 -0.000      3   0.0000      -  warnings::register::import
       0.00   0.000 -0.000      6   0.0000      -  warnings::register::mkMask
       0.00   0.000 -0.000     29   0.0000      -  vars::import
      
        It looks like a lot of your time is being spent BEGIN time, at startup. You might want to try the approach I suggest here: Re^3: Why can code be so slow? to see if startup time is dominating your application.

        If it is, the best solution is probably to avoid repeated startup (by using mod_perl or FastCGI) rather than optimising startup by avoiding CPAN modules.

Re^3: Why can code be so slow?
by BrowserUk (Patriarch) on May 01, 2007 at 18:50 UTC
    I will say that in this type of microbenchmark, ...

    Instead of denigrating other peoples efforts to produce objective measurements, why not (help) produce a better benchmark?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.