Greg Heo

Benchmarking PHP

Featuring PEAR's Benchmark module.

I recently needed some quick code timing information so I wrapped some function calls with $current = time() and then subtracted the results. Then I tried it with microtime() instead. Then I decided to browse PEAR for some kind of benchmarking tool.

Here are some notes on what PEAR’s Benchmark has to offer.


Benchmark_Iterate is the classic “run something n number of times” kind of benchmark. It returns the time each execution took as well as the mean.

require_once 'Benchmark/Iterate.php';

function doSomething($arg)
    return $arg += 100;

$benchmark = new Benchmark_Iterate;
$benchmark->run(100000, 'doSomething', 100);
$results = $benchmark->get();


Benchmark_Timer allows you to set markers at various points in your code. It keeps track of the time elapsed between markers as my original time() and microtime() example did.

require_once 'Benchmark/Timer.php';

$timer = new Benchmark_Timer();

$timer->setMarker('start work');
for ($i=0; $i < 100000; $i++) {
  $a = sprintf("%.2f", $i);
$timer->setMarker('end word');

$results = $timer->getProfiling();

The display() method will print out a table with your results. Or, you can access the raw results with getProfiling().


Benchmark_Profiler is similar to Benchmark_Timer except it’s meant to be enclosed in function and methods. You can also nest various things.

require_once 'Benchmark/Profiler.php';
$profiler = new Benchmark_Profiler();



Not as simple as that though; doSomething() and doSomethingElse() look like this:

function doSomething() {
    global $profiler;

    // do lots of work

function doSomethingElse() {
    global $profiler;

    // do even more work

Note the nested call in doSomethingElse(). Benchmark_Profiler will handle this correctly and show the profile results as expected.

As with Benchmark_Timer, the output() method will print out a table with your results. You can get at the data for a particular section by passing the section name to getSectionInformations() or data for all sections with getAllSectionsInformations().

That’s it

Remember, profile before optimizing.