The Perl You Need to Know: Benchmarking Perl Page 5

Once again, we see that there can be significant differences between approaches to the same problem in Perl - hopefully compelling enough numbers to convince the Web developer to take benchmarking seriously. Visitors to a Web site never like to wait, no matter how much magical hoo-hah the back-end script is performing. Given the causes of delay that are difficult to control, such as network traffic and latency, and the flexibility of Perl, it makes that much more sense to optimize the slowest portions of your own code.

Run-time Timing

While the benchmarking examples we've seen so far are compelling, they've also been measured under laboratory conditions - in this case, over many interations, outside of the context of a larger script. As well, if you already have a large script and want to start benchmarking, it may not be feasible to start coding alternative subroutines all over the place.

Sometimes, a simple stopwatch approach is enough to draw your focus to problem areas (no, not those problem areas). Using Benchmark, we can simulate a stopwatch where we simply want to trigger timing at a certain point in a script, and then stop timing, and spit out the results, without stopping the flow of the script.

So, imagine a back-end script that outputs some results to the browser. Maybe we simply want to time the execution of the entire script.

        #This is an amazing back-end script

        use Benchmark;
        use Time::HiRes;
        use LotsOfOtherStuff;

        my  = new Benchmark;

        ...all of the control code for the script...

        my  = new Benchmark;
        print "Script Benchmark: ".timestr(timediff(,));
Notice the use of Time::HiRes, which can help with reporting benchmark times for fast scripts, where small fractions of a second should be measurable. Like a stopwatch, we simply take note of the time at the start of the script, and again at the end, and report the difference. Assuming this is a CGI script the results will probably be printed to the Web page (also assuming proper headers, etc.), but you might alternatively wish to open a filehandle to a log file and send the print function to the log file.

Timing the entire script execution like this can be enlightening, but should also be interpreted with caution. For one, remember that this timer measures only the execution time of the script, not the time it takes for its output to reach your browser. Network performance is not being measured here. Web server performance is also not generally being measured, although in some cases -- such as Apache with mod_perl - these numbers are partially reflecting the Web server's performance at executing Perl code.

To get more use out of the stopwatch technique, consider adding several stopwatches to your script, wrapped around different portions of code. This way, you can get inside the machine's head and see a behind-the-scenes peek at which portions of code are taking how long to execute. A particularly effective technique is to wrap each subroutine inside a stopwatch. Simply:

        sub mySubroutine {
         my  = new Benchmark;
         ...original subroutine code...
         my  = new Benchmark;
         print "mySubroutine benchmark: ".

This article was originally published on Jan 23, 2001

Thanks for your registration, follow us on our social networks to keep up-to-date