{"id":1345,"date":"2018-01-19T19:22:44","date_gmt":"2018-01-19T19:22:44","guid":{"rendered":"http:\/\/goofy-trucks.flywheelsites.com\/profiling-php-code-with-xdebug-and-kcachegrind\/"},"modified":"2018-01-19T19:24:43","modified_gmt":"2018-01-19T19:24:43","slug":"profiling-php-code-with-xdebug-and-kcachegrind","status":"publish","type":"post","link":"https:\/\/phpbuilder.com\/profiling-php-code-with-xdebug-and-kcachegrind\/","title":{"rendered":"Profiling PHP Code with Xdebug and KCacheGrind"},"content":{"rendered":"<div class=\"phpbuilder-content\">\n<div class=\"phpbuilder-meta\">\n<div class=\"\">By W. Jason Gilmore<\/div>\n<div class=\"\">on December 30, 2010<\/div>\n<\/p><\/div>\n<div id=\"overflow-content\">\n<div class=\"articlePara\">In his 1974 paper, &#8220;Structured Programming with go to Statements&#8221;, famed computer scientist <a href=\"http:\/\/en.wikipedia.org\/wiki\/Donald_Knuth\" target=\"newFrame\">Donald Knuth<\/a> famously proclaimed premature optimization to be &#8220;the root of all evil.&#8221; While it is indeed a good idea to avoid spending too much time on code optimization during the early stages of any project, eventually you&#8217;ll want to seek out and resolve any bottlenecks in order to ensure your application is operating at its full potential.<\/div>\n<div class=\"articlePara\">Which brings us to the question of how to even go about determining which parts of an application could conceivably be optimized. One common approach involves using a profiler such as <a href=\"http:\/\/www.xdebug.org\/\" target=\"newFrame\">Xdebug<\/a>, which can analyze your code and produce performance reports. These reports can then be reviewed within a profiling visualization tool such as <a href=\"http:\/\/kcachegrind.sourceforge.net\/\" target=\"newFrame\">KCacheGrind<\/a>.<\/div>\n<div class=\"articlePara\">In this article I&#8217;ll show you how to use Xdebug and KCacheGrind to begin profiling and analyzing your PHP-driven Web applications.<\/div>\n<h2>Installing Xdebug<\/h2>\n<div class=\"articlePara\"><a href=\"http:\/\/www.xdebug.org\/\" target=\"newFrame\">Xdebug<\/a> is a powerful open source PHP debugging and profiling tool. Although you&#8217;re free to compile Xdebug from source, the easiest installation approach involves using PECL:<\/div>\n<div class=\"example\"><code><\/p>\n<pre>%&gt;pecl install xdebug<\/pre>\n<p><\/code><\/div>\n<div class=\"articlePara\">Once installed, add the following lines to your <code>php.ini<\/code> file:<\/div>\n<div class=\"example\"><code><\/p>\n<pre>zend_extension=\"\/full\/path\/to\/xdebug.so\"\nxdebug.profiler_enable = 1\nxdebug.profiler_output_dir = \/var\/www\/xdebug\/\nxdebug.profile_output_name = cachegrind.out.%t-%s<\/pre>\n<p><\/code><\/div>\n<div class=\"articlePara\">Of course, you may want to change the <code>xdebug.profiler_output_dir<\/code> setting to a more desirable location. After saving the <code>php.ini<\/code> file, restart Apache in order for the changes to take effect.<\/div>\n<div class=\"articlePara\">Keep in mind that this will cause profile reports to be created every time a PHP script is run on this Web server. If you want to profile scripts selectively, add the following line to your <code>php.ini<\/code> file:<\/div>\n<div class=\"example\"><code><\/p>\n<pre>xdebug.profiler_enable_trigger=On<\/pre>\n<p><\/code><\/div>\n<div class=\"articlePara\">After restarting Apache, you&#8217;ll be able to profile scripts selectively by appending <code>?XDEBUG_PROFILE=1<\/code> to your URL.<\/div>\n<h2>Installing KCacheGrind<\/h2>\n<div class=\"articlePara\"><a href=\"http:\/\/kcachegrind.sourceforge.net\/\" target=\"newFrame\">KCacheGrind<\/a> is available for installation from within most operating systems&#8217; software repositories. For instance, if you&#8217;re running Ubuntu you can install KCacheGrind using the following command:<\/div>\n<div class=\"example\"><code><\/p>\n<pre>%&gt;sudo apt-get install kcachegrind<\/pre>\n<p><\/code><\/div>\n<div class=\"articlePara\">If you&#8217;re running Windows, check out <a href=\"http:\/\/sourceforge.net\/projects\/wincachegrind\/\" target=\"newFrame\">WinCacheGrind<\/a>.<\/div>\n<h2>Creating a Profile Report<\/h2>\n<div class=\"articlePara\">With Xdebug and KCacheGrind installed, you can begin profiling your PHP scripts. If you opted not to enable the <code>xdebug.profiler_enable_trigger<\/code> configuration directive, then a new report will be created every time you execute a PHP script from within your browser. Each time you do so, a file will be created within the designated reporting directory, which looks like <code>cachegrind.out.1447<\/code>. The contents of this file aren&#8217;t intended for human consumption, but rather should be passed to an analysis tool such as KCacheGrind.<\/div>\n<div class=\"articlePara\">Loading the report into KCacheGrind opens a world of insight in terms of your ability to know for certain which operations are the most expensive. For instance, consider the output presented in Figure 1, which presents the call stack for a Zend Framework- and <a href=\"http:\/\/www.developer.com\/db\/article.php\/3887336\/Doctrine-Object-Relational-Mapping-for-Your-PHP-Development.htm\">Doctrine<\/a>-driven project I&#8217;m currently working on.<\/div>\n<div class=\"articlePara\"><a href=\"https:\/\/phpbuilder.com\/wp-content\/uploads\/2018\/01\/OptimizingPHP_figure1.png\" target=\"newFrame\"><br \/>\n<br \/><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/phpbuilder.com\/wp-content\/uploads\/2018\/01\/OptimizingPHP_figure1.png\" width=\"350\" height=\"151\"\/><br \/><font size=\"1\"><em>Click here for larger image<\/em><\/font><\/a><br \/>\n<br \/><font size=\"2\"><strong>Figure 1.<\/strong> Viewing a Zend Framework Action Call Stack<\/font><\/div>\n<div class=\"articlePara\">I&#8217;ve sorted the execution time of each call in order to determine which calls are the most expensive. The call to the <code>Default_Model_Platform<\/code> model&#8217;s <code>hot()<\/code> method ranks up towards the top, and because I know this data changes only every few hours, now I can safely cache it and thereby eliminate this expensive database query (which is indeed a fairly large <code>JOIN<\/code> operation). After implementing caching I again profile the page and indeed have eliminated that expensive call altogether (see Figure 2).<\/div>\n<div class=\"articlePara\"><a href=\"https:\/\/phpbuilder.com\/wp-content\/uploads\/2018\/01\/OptimizingPHP_figure2.png\" target=\"newFrame\"><br \/>\n<br \/><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/phpbuilder.com\/wp-content\/uploads\/2018\/01\/OptimizingPHP_figure2.png\" width=\"350\" height=\"150\"\/><br \/><font size=\"1\"><em>Click here for larger image<\/em><\/font><\/a><br \/>\n<br \/><font size=\"2\"><strong>Figure 2.<\/strong> Caching Removes the Expensive Query Altogether<\/font><\/div>\n<\/div>\n<p><\/p>\n<div style=\"float: left; padding:15px; color:#17AAF3\">\n<div style=\"background-color:#B6E5FC; font-size:16px; margin-top:1px; padding:1px 4px 1px 4px; color:#000; font-style:bold; float:left;\">1<\/div>\n<div style=\"float:left; font-size:16px; color:#FF7A22; padding:2px 2px 2px 2px; \">| <\/div>\n<div style=\"float:left; padding:2px 4px 2px 4px;\"><a class=\"pageNumber\" href=\"Jason_Gilmore123020104658.html?page=2\">2<\/a> <\/div>\n<div style=\"float:left; padding:2px;\"><a class=\"paginationPageLink\" href=\"Jason_Gilmore123020104658.html?page=2\">Next Page \u00bb<\/a><\/div>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to use Xdebug and KCacheGrind to begin profiling and analyzing your PHP-driven Web<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1345","post","type-post","status-publish","format-standard","hentry","category-tutorials"],"_links":{"self":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts\/1345","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/comments?post=1345"}],"version-history":[{"count":1,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts\/1345\/revisions"}],"predecessor-version":[{"id":2168,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/posts\/1345\/revisions\/2168"}],"wp:attachment":[{"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/media?parent=1345"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/categories?post=1345"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/phpbuilder.com\/wp-json\/wp\/v2\/tags?post=1345"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}