> > However, I've noticed that scripts that generate lot of output take > > substantially longer to run than their CGI counterparts. > > > > The CGI script took 1.59 seconds to run, whereas the mod_perl version > > took 3.38 seconds. It generates about 321K of output. > > Are you positive that they generated identical output?
The output isn't quite identical -- there are some differences because of differing script names and whitespace. But they're within a few hundred bytes of each other. > How were you doing this filtering in your CGI script? I had a written an SSI parser in Perl. It's not exactly optimized and is about six years old, but it basically recursed through INCLUDE directives until it found a script or other SSI directive to execute. Script output was captured by doing print `script`; > > I'm guessing that it's because Apache::Filter loads the output of > > each filter into memory before passing it on. > > That's a good guess. Why don't you profile it and find out where the > problem is? Try Apache::DProf. Hey, neat. :) I didn't know about that. Here's the output after a few loads: # dprofpp -F 24939/tmon.out Faking 2 exit timestamp(s). Total Elapsed Time = -0.05622 Seconds User+System Time = 0 Seconds Exclusive Times %Time ExclSec CumulS #Calls sec/call Csec/c Name 0.00 6.359 6.347 8921 0.0007 0.0007 Apache::Filter::PRINTF 0.00 1.163 8.016 3 0.3877 2.6719 Apache::RegistryFilter::handler 0.00 0.410 0.397 8996 0.0000 0.0000 DBI::st::fetchrow_arrayref 0.00 0.050 0.050 16 0.0031 0.0031 DBI::st::execute 0.00 0.050 0.099 2 0.0250 0.0494 Apache::SSI::handler 0.00 0.030 0.030 6 0.0050 0.0050 CGI::new 0.00 0.030 0.030 8 0.0037 0.0037 CGI::AUTOLOAD 0.00 0.020 0.030 65 0.0003 0.0005 Apache::PRINT 0.00 0.020 0.030 1 0.0200 0.0298 Apache::DBI::childinit 0.00 0.010 0.010 15 0.0007 0.0007 Apache::send_cgi_header 0.00 0.010 0.010 6 0.0017 0.0017 CGI::Util::expires 0.00 0.010 0.010 4 0.0025 0.0025 vars::import 0.00 0.010 0.010 11 0.0009 0.0009 DBI::_new_dbh 0.00 0.010 0.010 24 0.0004 0.0004 DBI::db::prepare 0.00 0.010 0.048 12 0.0008 0.0040 Apache::Registry::handler It looks like the problem is repeated print statements. I basically had a loop that did while ($ref = $sth->fetchrow_arrayref()) { print $$ref[0], $$ref[2], etc. } Changing it to my $output; while ($ref = $sth->fetchrow_arrayref()) { $output .= $$ref[0] . $$ref[2], etc. } print $output; cut the load time to 1.03 seconds -- that's 1/3 of the timing with multiple print statements and 2/3 of the timing for the CGI script. So the lesson I learned is to store all of your output when using Apache::Filter, then print it all out at once. Thanks for the pointer, Perrin! Chris -- Reporting bugs: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html