Saturday, May 12, 2012

Improve Performance by Profiling Web Applications


Since web seems to be a trend these days most of the new comers try to make alive their fascinating business ideas through web applications. They use nice UI components for their application to make it attractive. Initially they don't worry about the performance of the application because they won't feel it makes a huge impact at this moment. Even though your application is not an optimized design, you won't see it for a small set of data. But it really matters while your application grows. If there are some non optimized plugins, classes or functions running in your application it may slow down your application when it handles large data sets.

At this point you may wonder how to deal with this. If your application has only couple of classes you will be able to go through the code and identify bottlenecks in your application. But what if it is a application with 100+ classes. You can't go through it manually. That's where "Profiling Tools" act as life savers of developers. 

Profiling tools debug the web application and keep the records of your application at run time. Then it interpret those records to visualize execution process of each code segment in module level, class level and function level.  Using these output developer can identify 
  • what is the hierarchy of classes/ functions running on this action
  • How may time each class/function get called by parents
  • what are the execution time of each segment.
Bases on this developer can see what are the classes/functions which took most of the execution time in your applications and identify performance bottlenecks of the application. To get a basic idea on profiling tools, I'll explain how to profile a PHP application with Xdebug and KCacheGrind.

Xdebug is a PHP extension which facilitate the developer to debug and profile web applications. While you running the application xdebug tack all the events running on the application(by tracking the server) and log it to a file. This file contains stack trace information, function trace information, memory allocation and many more useful information. We can visualize those data using a visualize tools.  

KCacheGrind is a data visualization tool which is used as a profiler frontend. We can use KCacheGrind to open the Xdebug output file and analyze its output in a meaningful manner. 

Following are the simple steps to install Xdebug and KCachegrind in Ubuntu to profile your application. 

Install Xdebug

Install it via pecl is easy and reliable. 
pecl install xdebug

Enable it by adding the following file path to php.ini or xdebug.ini file.(Use full path)
zend_extension=/usr/lib/php5/20090626/xdebug.so

Then activate debugging by enabling following features in xdebug.ini file or php.ini file. 

Enable all requests to profiling
xdebug.profiler_enable = 1

In some occasions you may need to skip some requests and only profile selected requests. To enable only GET/POST requests or COOKIE with name XDEBUG_PROFILE you have to enable following property.
xdebug.profiler_enable_trigger = 1
Following properties are also important to make your life easy with xdebug. 

Append the output at each time when same request comes to the server. 
xdebug.profiler_append=1

Name of output files
xdebug.profiler_output_name = cachegrind.out.%s

Name of the output directory (This directory should have write permissions).
xdebug.profiler_output_dir=/tmp/xdebug

Now you are done with configuration process. Restart the web server to apply your  changes. 
/etc/init.d/apache2 restart

Install KCacheGrind

Install it via the OS package manager. 
apt-get install kcachegrind

There are some alternatives to KCacheGrind. WebGrind is a web based tool which has subset of features of KCacheGrind. But KCacheGrind is rich in features so I recommend it. 

How to profile your application

Now you are armed with enough tools to profile your application. Now access your web application through the browser and run the necessary page which needs to be profile. After a success full page load, you can find the corresponding xdebug output file in /tmp/xdebug directory. Now you can open it using KCacheGrind to visualize the output. 

kcachegrind
As an example run the following code on your browser to examine output. 

//test.php
function innerLoop($limit) {
    for($count = 0; $count < $limit; $count++) {
        echo "*";
    }
}   
  
function outPut($rows) {
    for($count = 1; $count <= $rows; $count++) {
        innerLoop($count);
        echo "
";
    }
}

outPut(10); 

Output of xdebug will be as follows.


Flat Profile will list all the events run in your application as follows. By default events are sorted in the order of time taken.



Following are the explanation on the values displayed in this table. 
  1. Incl - Total value that event took
  2. Self - Time spent only within that event
  3. Called - Number of times that event get called
  4. Function - Function name
  5. Location - File
And also KCacheGrind provide a execution graph which simplify above data. You can get that by selecting "Call Graph" tab  of each event. 


With these you can find the time each event spent on executing, the hierarchy of events and how many times each event get called by other. This is a nice interpretation which help developer to find issues is huge web systems. When we consider large systems which were build on frameworks as Zend or Symfony, there are number of utility functions running in the background. So the "Flat Profile" will be too complicated to get an quick decisions. Following screenshot is a part of the flat profile of an application which was built on top of Symfony. 


This is too complected and most of the events are related to framework. We can use "Call Graph" in similar situations to make our life easy.  Following is a part of the "Call Graph" of it. 


This nicely shows the execution path and you can get quick decisions based on this. 

Likewise there are more advance options in KCacheGrind which helps you to profile your application. Tryout those options and find most suitable options to profile your application which will lead to have a smart web application at the end of the day.