Tuesday, February 8, 2011

How do I profile a Perl web app?

I am working on a web app that uses Perl and I need to look into speeding up portions of the app.

I thought I'd start profiling the particular calls for the portion I wish to investigate. I've done some searching on profiling Perl code, but unfortunately most of what I find says that I should run my perl code with -d:DProf myapp from the command line. That doesn't quite work for me since my code is within a web app. I did find a way to get the profiling to work with apache, but unfortunately, the "most used" modules that came back from the profiler were all CPAN modules -- Class::xyz, etc etc etc. Not terribly helpful.

Does anyone know of a good way besides me injecting "timer" code into the methods I wish to profile to target just these methods? I've thought of writing a test script and profiling that but due to the nature of the code I'm working on that would require a bit more work than I'm hoping to have to do.

  • You can use the Benchmark core module with the :hireswallclock option if you really want to time things internally. But really, you should be able to profile from the command line. You might have to write test scripts to emulate certain portions of a CGI request, but DProf can be extremely useful when looking for performance bottlenecks.

    In particular, look for where your code is calling the CPAN module code. You may be doing this in loops far more than necessary, so while the time is spent in the CPAN module, refactoring your code can fix the problem.

  • Have you tried Devel::NYTProf (much better than Devel::DProf), which can work under Apache? Which webserver are you using? Is this a vanilla CGI script, a mod_perl thing, or something else?

    The real trick, however, is to organize the code so that you can do the full spectrum of testing and profiling without having to put it all together at the end to find out something is slow. That won't help you much in the short term to fight fires, but it does prevent things from becoming fires in the long run. There are also various ways to fake the webserver environment and so on, but that's a different question. :)

    Leanan : Yeah, that's the one I tried, and all it turned up was all the cpan modules. I want to actually target these specific methods and see where they themselves are spending most of the time.
    mpeters : Which CPAN modules did it list? If you're doing a lot of database calls then it's quite possible that DBI and DBD modules will be at the top of your list. This isn't because Perl is doing too much work, but because your DB queries are slow. Start profiling them instead.
  • If you're using CGI.pm, you can pass arguments to your perl script on the command line and CGI.pm will interpret them as if they were passed as parameters over HTTP. So if you're debugging, e.g.

    http://example.com/scripts/example.pl?action=browse&search=grommet&restrict=blah

    then you could just call from the command line, e.g.

    perl -d:NYTProf documentroot/scripts/example.pl 'action=browse&search=grommet&restrict=blah'

  • I realize it's a bit late for it at this point, but this is one of the reasons why it's good to use CGI::Application or another architecture in which the web app is just a very brief bit of web-facing code which makes use of a bunch of modules you've written to implement the actual functionality. Using such a design makes it very straightforward to profile (or simply test) any modules from the command line, either individually or collectively, without having to worry about the web aspect.

0 comments:

Post a Comment