Skip to content

Instantly share code, notes, and snippets.

@paleo9
Last active September 11, 2017 21:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paleo9/6ee58e76e6465ba1693dcbe54d07620b to your computer and use it in GitHub Desktop.
Save paleo9/6ee58e76e6465ba1693dcbe54d07620b to your computer and use it in GitHub Desktop.
PHP Profiling

PHP Profiling with XDebug Profiler

Profiling shows up any bottlenecks in a program, it gives real metrics that can be analysed. Looking at the code and making educated guesses at the problem areas is usually ineffectual.

We need to profile the whole user experience so that it includes complex JavaScript and external effects due to latency and distance, load balancers and so on. Usefule tools may be Graphite, LogStash. But that's for another article. Here I am just dealing with backend.

Tools

  • xhprof: Doesn't support PHP7. No detraction on performance so can be used on production servers. Can use it on s specified subset of data. It was developed by Facebook.
  • Tideways: a fork of xhprof, it costs money but there is a 30 day free trial available.
  • xdebug profiler: venerable but it works with php7.0 and it's opensource. It slows the program considerably so not suitable for production server, also speed benefits may be greater than indicated.
  • cachegrind: companion to xdebug profiler in various forms - kCacheGrind, qCacheGrind and as a web app, WebCacheGrind.

Installing Xdebug Profiler

At the time of writing I am using Debian Testing for development. The xdebug package installs php7.0, so that is being used with apache. Install xdebug:

apt-get install php-xdebug

relevant values from /etc/php/7.0/php.ini:

; xdebug debugging
zend_extension=/usr/lib/php/20151012/xdebug.so
  xdebug.remote_enable=1
  xdebug.remote_enable=0
  xdebug.remote_handler=dbgp
  xdebug.remote_host=local
  xdebug.remote_port=9000

; xdebug profiling
 xdebug.profiler_enable=0
 xdebug.profiler_enable_trigger = 1
 xdebug.profiler_output_dir = /tmp
 xdebug.profiler_output_name = cachegrind.out.%R.%t

With the enable_trigger set to 1, we can profile any page by adding XDEBUG_PROFILE to the end of the url. The alternative is to set profiler_enable=1 and turn off trigger. This would profile every time.

By default the output is sent to a file in the tmp directory which we can we can pass on for viewing by kCacheGrind, WebCacheGrind or similar. The php.ini options for output_dir and output_name may be used - the directory must be writeable by PHP. Output from phpinfo() gives the following.

inifile item                               |  value
-------------------------------------------|-----------
xdebug.profiler_aggregate                  | Off
xdebug.profiler_append                     | Off
xdebug.profiler_enable                     | Off
xdebug.profiler_enable_trigger             | On
xdebug.profiler_enable_trigger_value       | no value
xdebug.profiler_output_dir                 | /tmp
xdebug.profiler_output_name                | cachegrind.out.%p

 xdebug.remote_addr_header                 | no value
 xdebug.remote_autostart                   | Off
 xdebug.remote_connect_back                | Off
 xdebug.remote_cookie_expire_time          | 3600
 xdebug.remote_enable                      | On
 xdebug.remote_handler                     | dbgp
 xdebug.remote_host                        | localhost
 xdebug.remote_log                         | no value
 xdebug.remote_mode                        | req
 xdebug.remote_port                        | 9000

Usage

Having got profiling in the browser working in Debian, and setting values in /etc/php/7.0/apache2/php.ini we can run the profiler:

every time a php page is loaded

xdebug.profiler_enable = 1
xdebug.profiler_enable_trigger = 0

only when required

xdebug.profiler_enable = 0
xdebug.profiler_enable_trigger = 1

for this method, run as http://localhost/phpinfo.php?XDEBUG_PROFILE and view the results using kcachegrind. Remember that the results will be significantly slower than in production.

Useful links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment