PHP DevCenter
oreilly.comSafari Books Online.Conferences.

advertisement


Improving Performance by Profiling PHP Applications
Pages: 1, 2

A Benchmark Anecdote

The example was good, but it is really not a good example of how to make decisions related to your site, and especially to your site code. I will use a personal experience that I had while working as a contractor for a company that had a huge Web community on a niche Web site and was having performance problems.



I really didn't understand much of the code because it was written along the years with specific needs -- one block of include files relating to the site translation code, another one to log the site's usage, and so on. We both knew (me and the main programmer of that site) that something needed to be optimized, but didn't know what the problem was.

To shorten the story, I ended up going into the main script and adding several lines of $bench->setMarker() all over the script and its included files. We then analyzed the output of $bench->getProfiling() and were surprised by the outcome. It seemed that the problem was actually related to a function call that was being used hundreds of times on every page to get the translation code for a specific language name (i.e. "en" for "english"). Every time the function was called, the script would do a query to a MySQL database to get the real name from a table.

Related Reading

Programming PHP
By Rasmus Lerdorf, Kevin Tatroe

We ended up creating a cache system for this type of information. In two days we had a huge performance boost, and consequently the number of page views increased by 40% in the first week. All in all, this serves as an interesting example of how profiling your code can help on the general health of your Web application or Web site.

Benchmarking Function Calls

While the Benchmark_Timer() class is very useful in profiling the code on a script or page (and its included files), it is not very scientific, since you have to reload the script several times to get the mean of the profiled values, and it is not very specific to a class or function call.

The other class in the PEAR::Benchmark library, called Benchmark_Iterator, is intended to tackle this very issue -- running a series of executions for a very specific function or class method and displaying its profiling information. Its purpose is to get a consistent response from the benchmarks, since everybody knows that running a script one time and receiving an execution time of 10 seconds doesn't mean that it always performs like that.

In any case, let's see some examples:

<?php
// code to connect to the database here
include_once("DB.php");
$dsn = array(
    'phptype'  => 'mysql',
    'hostspec' => 'localhost',
    'database' => 'database_name',
    'username' => 'user_name',
    'password' => 'password'
);
$dbh = DB::connect($dsn);

function getCreatedDate($id)
{
    global $dbh;

    $stmt = "SELECT created_date FROM users WHERE id=$id";
    // as always, let's use PEAR::DB here
    $created_date = $dbh->getOne($stmt);
    if ((PEAR::isError($created_date)) || 
	    (empty($created_date))) {
        return false;
    } else {
        return $created_date;
    }
}

include_once 'Benchmark/Iterate.php';
$bench = new Benchmark_Iterate;

// run the getDate function 10 times
$bench->run(10, 'getCreatedDate', 1);

// print the profiling information
print_r($bench->get());
?>

The code above will generate output similar to this:

Array
(
    [1] => 0.055413007736206
    [2] => 0.0012860298156738
    [3] => 0.0010279417037964
    [4] => 0.00093603134155273
    [5] => 0.00094103813171387
    [6] => 0.00092899799346924
    [7] => 0.0010659694671631
    [8] => 0.00096404552459717
    [9] => 0.0010690689086914
    [10] => 0.00093603134155273
    [mean] => 0.0064568161964417
    [iterations] => 10
)

This should be pretty self explanatory -- the mean item shows the average value for all 10 iterations of the getCreatedDate() function. The benchmark should probably run for more than a thousand iterations, but this example is good enough :).

I hope that with this article I've given some insight into practical ideas of how to quickly profile PHP scripts. Please be aware that analyzing your code is not something simple, as you need to know a lot about the language's specific features. However, adding timers while testing your code will help you isolate the sluggish functions and using iterations will help test them until you figure out the correct optimizations.

Joao Prado Maia is a web developer living in Houston with more than four years of experience developing web-based applications and loves learning new technologies and programming languages.


Return to the PHP DevCenter.




Valuable Online Certification Training

Online Certification for Your Career
Earn a Certificate for Professional Development from the University of Illinois Office of Continuing Education upon completion of each online certificate program.

PHP/SQL Programming Certificate — The PHP/SQL Programming Certificate series is comprised of four courses covering beginning to advanced PHP programming, beginning to advanced database programming using the SQL language, database theory, and integrated Web 2.0 programming using PHP and SQL on the Unix/Linux mySQL platform.

Enroll today!


Sponsored by: