Eric Hogue on March 30th, 2011

When developing web applications, we often run into performance issues. People often blame PHP or MySQL for bad performance, but in most case the answer is not that easy. Blindly trying to optimize random parts of our applications can lead to some uneven results.

There are many available tools to profile a PHP application. Learning how to use them can help us pinpoint which parts are slow. With this information we can pick the optimizations that will give us the best results.

This post describes the installation and configuration of some of them. I tested them in a Ubuntu 10.10 virtual machine. If you want to try those tools, don’t forget that they can greatly impact the performance of you web server when they are active. Installing a tool like Xdebug on a production server is not recommended.

Benchmark Your Application

First you need to benchmark your application. If you don’t, you won’t be able to know if you improve the performance or degrade it. If you make some changes, a gut feeling that the site is faster is not enough, you need to have numbers. Siege is a load testing tool. It will tell you how many request a second your application handle and the response time.

Installing Siege is pretty straightforward, download it, untar it and compile it with make.

tar -xvf siege-latest.tar.gz
cd siege-2.70/
./configure
make
sudo make install
siege.config

Running siege.config will generate a .siegerc file. You might need to edit it and change where the log file is generated. By default, the logs where stored in /var/siege.log and I didn’t want to run it as root. So I uncommented the logfile line to store it in my home folder. You might want to set verbose to false also.

When Siege is install, you can use the following command to execute it for 30 seconds with 5 concurrent connections.

siege -c 5 -b -t30s http://localhost
** SIEGE 2.70
** Preparing 5 concurrent users for battle.
The server is now under siege...
Lifting the server siege.. done.
Transactions: 143 hits
Availability: 100.00 %
Elapsed time: 29.75 secs
Data transferred: 0.27 MB
Response time: 1.02 secs
Transaction rate: 4.81 trans/sec
Throughput: 0.01 MB/sec
Concurrency: 4.92
Successful transactions: 143
Failed transactions: 0
Longest transaction: 1.54
Shortest transaction: 0.94

The results will be appended to the log file. This makes it easy to compare the numbers after you make some changes. You can also see when the performances really start to degrade if you add users.

Xdebug

Xdebug is a debugger for PHP. I already talked about it in my post on Debugging PHP In Eclipse. It can also be used for profiling. You can install it with Apt.

sudo apt-get install php5-xdebug

To configure it, open the Xdebug ini file, on standard Ubuntu it’s in ‘/etc/php5/conf.d/xdebug.ini’. Add these lines:

xdebug.default_enable=1
xdebug.scream=1
xdebug.profiler_enable=1
xdebug.profiler_output_dir=/tmp/xdebug

This will make sure that Xdebug append a stacktrace to errors. And the scream option will disable the PHP error control operator (@). This way all errors will be displayed. It enable the profiler and change it’s output folder. Make sure the folder exits and that apache can write in it.

When Xdebug is installed and configured, restart Apache and browse to your web application. Xdebug will create some files in the folder you picked. You can then use KCachegrind to view those files. You can install it with this command:

sudo apt-get install kcachegrind

On a Gnome machine, this will install lots of dependencies. But after, you will be able to open the output file from Xdebug. You should get a window that looks like this:

KCachegrind

KCachegrind Output

In KCachegrind you can see where your program spent most of it’s time. How many time a function is called. This information should help identify where you should start optimizing to get the most out of your time.

If you prefer a web front end, you can use Webgrind to inspect the result of Xdebug.

XHProf

Xdebug is a very good tool to check where your bottlenecks are in development. However, you should not use it in production. Facebook developed XHProf a profiling tool that can be used on a production server.

To install it, download the latest version and run those commands:

tar -xvf xhprof-0.9.2.tgz
cd xhprof-0.9.2/extension/
phpize
./configure --with-php-config=/usr/bin/php-config5
make
make test
sudo make install

Edit your php.ini and add those line at the end:

[xhprof]
extension=xhprof.so
;
; directory used by default implementation of the iXHProfRuns
; interface (namely, the XHProfRuns_Default class) for storing
; XHProf runs.
;
xhprof.output_dir=/tmp/xhprof

Make sure to change the output dir to something appropriate on your machine.

To profile your application, you now need to add some code at the beginning and at the end of you page execution. Add this at the beginning:

xhprof_enable();

And this at the end:

$data = xhprof_disable();

$XHPROF_ROOT = '/home/testing/Downloads/xhprof-0.9.2';
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";

$xhprof_runs = new XHProfRuns_Default();

// Save the run under a namespace "xhprof".
$run_id = $xhprof_runs->save_run($data, "xhprof");

XHGui

XHGui is a tool that allow saving the data from XHProf in a database and displaying it in a nice UI. It also comes with two files that facilitates adding XHProf to your silte. To install it, clone the repository from GitHub. And follow the instructions in the INSTALL file. Here are the instructions for a machine using MySQL for storage.

git clone https://github.com/preinheimer/xhprof.git
cd xhprof
ln -s xhprof_lib/utils/xhprof_runs_mysql.php xhprof_runs.php
mv xhprof_lib/config.sample.php xhprof_lib/config.php

Look in the xhprof_runs.php file. There is a create table query. Create a database for XHGui and execute the query. Edit the file xhprof_lib/config.php and enter the information for your system. Don’t forget to set doprofile to true. Also, you need to uncomment one of the section for the paths where XHGui should put its files. There are default values for Windows and Linux.

XHGui comes with two files that makes profiling easier. A header file to start profiling and a footer that will end it and persist the information in your database. To automatically insert them in all your site, add the following lines to you virtual host:

php_admin_value auto_prepend_file "/home/testing/Downloads/xhprof/external/header.php"
php_admin_value auto_append_file "/home/testing/Downloads/xhprof/external/footer.php"

You will also need to create a virtual host for XHGui. Then after your site have been visited a few times, you can navigate to you XHGui installation and you will have a page that list the last 25 runs of your sites. Pick one and you should see a page like this one.

XHGui Run page

From this page you can view a lot of information about your pages. It contains statistics about the time the page took, the CPU and memory usage and the number of functions calls. At the bottom, there is a list of functions with the same information. It makes it easy for you to see where the page takes the most time or resources. This will help you find targets for optimizations that will really impact the use experience on your site or the machine where it runs. You can click on any function and view a break down of the functions it calls.

On the main page of a run and in the functions pages, you can generate a call graph with just on click.
XHGui Call Graph
It gives you a nice visual of the functions called when you display a page. The functions that can be problematics are in red or yellow, so you can spot the easily.

This Is Just The Beginning

This is only an introduction to some of the tools that are available for PHP developers. I want to play more with them, and maybe post more information when I get more familiar with them. If you don’t do any profiling, you should probably try them too.

One important rule when optimizing, always measure. Benchmark before and after every change to make sure you are going in the right direction.

Update 2011-04-01

php|architect announced yesterday their first Annual Impact Awards. They nominated quite a few amazing projects, the choices are not easy. However, I think XDebug is an outstanding tool that impact the work of many PHP developers every day. Derick Rethans is doing some important work with it. He has my vote for the award. If you are a php| architect subscriber, go cast your vote.

Tags: , , , , , ,

27 Comments on Profiling a PHP Application

  1. Mo says:

    Hadn’t heard of XHProf/XHGui – looks like I will have lots of fun playing around with these tonight! :D Thanks for the info.

  2. Eric Hogue says:

    @Mo I’m glad you liked it. I started this post 1 1/2 month ago and I had completely forgot about XHProf and XHGui. But at Confoo, Paul Reinheimer had a great talk about it.

  3. gabel says:

    Thx for this post. just wake the memory in my head to configure our env with xhprof :)

  4. Richard Tuin says:

    Great post Eric!
    Performance monitoring is an untouched subject for me, and this post is a great introduction!
    I’m definitely going to look into this a bit more

  5. Eric Hogue says:

    Gabel and Richard, I’m glad you liked it. I hoped it helps you a little. Thanks for your comments.

  6. PatForg says:

    Hey Erick, good post. I’ve been wanting to try XHProf/HXGui for while now. This will definately make it easier.

    For windows users that want to use KCachegrind to view XDebug’s output there is a windows port that can be found here: http://sourceforge.net/projects/precompiledbin/ which is the only one that allows you to see a detailed calltree. A much better than the other alternatives on windows.

  7. Jatin says:

    Eric :- It is an awesome tutorial. Normally an ordinary developer doesn’t spend much time and effort in this direction.

  8. Thanks Eric i have only used xdebug so far, definetly goinf to have a play with siege later and see how what the visuals stats of my codeigniter php apps look like in XHProf/HXGui.

  9. Eric Hogue says:

    Patrick: Thanks for the link for Windows developer. I don’t use Windows, so I’m out of touch with the available tools.

    Jatin: As developer we tend to optimize the areas that are often slow like the db. But if we cannot measure it, it’s hard to know the impact we made. And we might loose to much time optimizing a function or a query that is slow, but gets called once a year.

    Matthew: I hope you have fun with Siege, XHProff and XHGui. Let me know if you find anything useful with them.

  10. Gobezu says:

    For production use of xdebug one could use the option http://www.xdebug.org/docs/all.....le_trigger
    Thanks for the note about XHProf, had no idea it existed.
    Look forward to your further investigation in this area.

  11. Eric Hogue says:

    @Gobezu: I didn’t know about profiler_enable_trigger. Thanks for mentioning it.

  12. Gary says:

    Hi Eric,
    Thanks for your tutorial of the profiling tool for PHP. Actually, I’m a customer service representative of Application Performance Management solution. Most applications I have contacted are Java or DotNET.
    My client sent me a request about profiling PHP application recently. After read your article, I think XHProf is a good tool for monitor on production environment but it requires to change PHP code.
    Is there any way to monitor PHP application without change any code?

    Thank you very much.

    • Eric Hogue says:

      Hi Gary,

      Thanks for your comment. XHGui has 2 scripts that you can use to add the code needed by XHProf. You can setup your web server to inject the 2 scripts in every pages that are served. This way, it’s done through configuration and you don’t need to change your code.

      The code to do that in Apache is in the post above (look for php_admin_value). I don’t know how, but I’m sure you can do the same thing with nginx.

  13. Dinu says:

    There is a new module for profiling php scripts, which is much faster than XDebug; also supports recursion: http://exteon.ro/en/products/php-tools/web3tracer

  14. Satya says:

    Hi,

    We have a server side PHP script. Majorly, it interacts with MySQL Database (30+ tables) and performs some custom/business logic.

    For various reasons, we need to run 100+ instances of this script as a cron process. So, any given point of time, there are 100+ cron jobs running.

    We observe that ‘php’ is being placed always in the 1st 3 places in the output of ‘top’ command.

    We want to profile/debug this script in real time (production server) when 100+ instances are running and find out the bottlenecks.

    Please help how we can proceed. your inputs are highly valuable to us.

Trackbacks/Pingbacks

  1. [...] Hogue, a fellow PHP programmer up here in Montreal has written about Profiling a PHP Application.  It’s a solid step-by-step setup of XHProf, XHGui, Xdebug for profiling with kcachegrind, [...]

  2. [...] community member Eric Hogue has written a very interesting post about “Profiling a PHP Application” This is a problem that all developers should face. In his post, Eric gives a good rundown of three [...]

  3. [...] Hogue has written up a new post about a few different technologies you can use to profile your PHP applications quickly and easily. There are many available tools to profile a PHP application. Learning how to [...]

  4. [...] 針對效能調教的部份,除了上篇提到通用的xdebug之外,其實還有不少方便的工具可以讓開發者更容易對自己的程式進行測試或效能調教。有些在教父的演講中也有提到,主要會根據Profiling a PHP Application中所提到的工具來進行說明。 [...]

  5. [...] este foarte simplu (firebug, chrome/safari developer tools), în PHP e un pic mai… special. Iată aici cum poți face benchmarks și profiling la aplicațiile [...]

  6. [...] Read More Share this:ShareFacebook [...]

  7. [...] Profiling a PHP Application – …spricht für sich [...]

  8. [...] http://erichogue.ca/2011/03/li.....plication/ Teilen Sie dies mit:E-MailFacebookTwitterGefällt mir:LikeSei der Erste, dem dieser post gefällt. von → Uncategorized ← Facebook „push“t Nachrichten..? Wie geht das denn? Noch keine Kommentare [...]

Leave a Reply