[How2Tips] How to benchmark your code with xdebug

Reading time : 1 min

Dr Klein shares with you his thoughts about how to profile your php scripts, in a post extracted from our internal knowledge database.

Before we start, let’s just be aware that there are many ways to profile your apps :

  • xdebug
  • xhprof (by Facebook, almost dead)
  • FriendsOfPHP/uprofiler (renamed fork of xhprof, by Sensio, almost dead, prototype for blackfire)
  • xhmem (dead)
  • blackfire (Saas)
  • https://tideways.io/ (the php extension generates the same output as xhprof)

We’ll focus on xdebug for now. Always think of what you’re trying to achieve : in this case you are trying to isolate a performance bottleneck.
It’s thus a good idea to isolate the portion of code you’re trying to benchmark in a separate script. This way you’ll be able to run it via the CLI, which simplifies greatly the setup. Isolate your subject under test (SUT) : imagine you want to profile a Symfony service.

Just create a simple php script :


require __DIR__.'/../vendor/autoload.php';

use App\Symfony\AppKernel;

$kernel = new AppKernel('dev', false);
$container = $kernel->getContainer();

$container->get('expensive_service')->run(); // whatever

Activate the xdebug profiler

RTFM: https://xdebug.com/docs/all

The easiest is to punctually enable it via php -d :

php -dxdebug.profiler_enable=1 -dxdebug.profiler_output_dir=$(pwd) bin/test.php

Note: this will activate the profiler for this process only, and will put the cachegrind output in the current folder.

Cachegri- what??

Cachegrind is a format developed for valgrind (an analysis tool). The cool thing is that KcacheGrind, a KDE app, is the best cachegrind visualizer, and is available on Linux.


Once you generated a cachegrind file, just run it with kcachegrind <cachegrind.out.whatever>.
It will help you understand where php took most of its time.
It also generates nice call graphs.

Running with docker?

First, grasp the basics.
Don’t forget that containers are just UNIX processes. Nothing magical. If you don’t get UNIX processes, switch to Windows. Now that we’re on the same page, remember that the container has a different filesystem tree than your host one. In order to access the cachegrind files generated by xdebug, you’ll have to mount a volume, like in the following example:

docker exec -v $(pwd):/xdebug my_image php -dxdebug.profiler_enable=1 -dxdebug.profiler_output_dir=/xdebug /xdebug/bin/test.php

This will ask docker to mount your current folder as /xdebug, and it will dump the cachegrind files in it.
But we diverge, because that has nothing to do with xdebug.


Always verify if xdebug is correctly configured:

On your host:

php -i | grep profiler_enable

Or with docker:

docker exec my_image php -i | grep profiler_enable

It should display :

xdebug.profiler_enable => On => On

Any questions ? Ping us at @KNPLabs