This post assume that you have already installed and enabled xdebug on your lamp stack
To visualize profile data, you must have KCacheGrind and GraphViz. It should be easy to find versions suitable for your flavor of Linux. Debian users can quickly install KCacheGrind and GraphViz and all the packages’ dependencies using the Advanced Packaging Tool (APT).
$ sudo apt-get install kcachegrind graphviz
To profile your code, simply point your browser to your PHP application.
As an example, let’s profile the simple Prime Number Display, checkprime.php, shown below
<?php
function IsPrime($Num)
{
if($Num == 0) return 0;
else if($Num == 1) return 1;
$No = 0;
$Result=0;
for($CurrNum = 2; $CurrNum <= $Num; $CurrNum++)
{
for($Divisor = 2; $Divisor < $CurrNum; $Divisor++)
{
$Res = $CurrNum / $Divisor;
if($Res != 1 && intval($Res) == $Res)
{
$No = 1;
$Divisor = $CurrNum;
}
}
if($No != 1)
$Result = $CurrNum;
$No = 0;
}
// If the only divisor is the number itself, it's prime
if($Result == $Num)
return 1;
else
return 0;
}
?>
<html>
<head>
<title>Prime Number Display</title>
</head>
<body>
<h2>Try the Prime Number Display!</h2>
<form action="checkprime.php" method="POST">
Enter a start number: <input type="text" name="start"></input>
Enter an end number: <input type="text" name="end"></input>
<input type="submit" name="Diplay"></input>
</form>
<hr />
<?php
if (isset($_POST['start']) && isset($_POST['end']))
{
$start = $_POST['start'];
$end = $_POST['end'];
for($i = $start; $i <= $end; ++$i)
{
if(is_prime($i))
{
echo '
'.$i.' ';
}
}
}
?>
</body>
</html>
Point your browser to http://localhost/checkprime.php (or the appropriate URL)
and enter 0 for start number and 100 for end number
If you list the contents of the profiler output directory (named in php.ini), you should see a file named something like cachegrind.out.18936. The prefix cachegrind.out. is fixed. By default, the numerical suffix is a CRC32 hash of the directory path to the checkprime.php file. Hence, if each of your applications lives in its own directory, output from each application is segregated by file name. (If you prefer to associate output with time, add this line:
xdebug.profiler_output_name = timestamp
to php.ini.)
Launch KCacheGrind and open cachegrind.out.18936. A new window resembling the figure below should open momentarily.
Click the Callees tab, double-click the highlighted line of source code, and choose Source File from the Grouping list. Your view should change to resemble to the screenshot below.
As you might expect, virtually all the processing time (95.16 percent of the 1753118 milliseconds) was spent executing 101 invocations of the function IsPrime(). To hasten this application, we can see that if the function IsPrime() could be re factored , it will benefit the whole timing of the application. Also, instead of checking all the numbers between the range, if we can put a small check on the numbers, if it can be a prime before calling the function IsPrime(), it will even reduce the numbers of times the function was called.
A smarter version of the IsPrime() function is shown below. Instead of 101 function calls, only 51 were required , and time was reduced to 2513 milliseconds.
<?php
function IsPrime($i)
{
$d = 3;
$x = sqrt($i);
while ($i % $d != 0 && $d < $x) $d += 2;
return (($i % $d == 0 && $i != $d) * 1) == 0 ? true : false;
}
?>
<?php
if (isset($_POST['start']) && isset($_POST['end']))
{
$start = $_POST['start'];
$end = $_POST['end'];
for($i = $start; $i <= $end; ++$i)
{
if($i % 2 == 1 || $i == 2)
if(IsPrime($i))
{
echo '
'.$i.' ';
}
}
}
?>

Conclusion
If your Apache installation is already optimized and your application is already cached, but your performance is lackluster, consider how the code is working. Is your algorithm efficient? Is the code too complex? Are you reimplementing a function that PHP already provides?
Certainly, if you cannot name or spot the bottlenecks, it’s time to find and fix the slowdowns. Don’t guess — profile! You may be surprised at how your precious compute cycles are being spent.
And never forget: Disable Xdebug on production servers, as it always adds overhead when enabled.





1 Response to “Profiling With Xdebug”