Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts

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. 

Saturday, March 17, 2012

How to use Mysql Transactions with PHP

Web applications are more popular today than ever with the increasing number of internet users. Most of the standard alone applications converted as web based applications or at least they try to provide a web interface for users. PHP and Mysql are two leading technologies which allow uses on rapid development of web based systems. "Transaction" is a powerful concept which comes with Mysql 4.0 and above versions. Lets explore that.

                                             

Web based applications have different types of requirements and some of them prefer more consistency on its data than others. As an example Banking software expect its data to be more secure and consistency. Assume a situation where one person (Bob) is transferring some amount of money (XXX) to his friends bank account (Alice) directly form account to account. The queries for the banking software database on this transaction will be as follows.

  1. Deduct XXX amount form Bobs account.
  2. Add XXX amount for Alices account.
If both queries executed successfully, it will be great. But assume a situation where the first query executed successfully and then the database connection get lost. At that situation the second query will not run on top of that database, so nothing will add to the Alices account. The deducted amount form the Bobs account will also not get recovered. These will make a disaster for Bob, Alice and for the Bank.

"Transactions" can solve this problem with a great solution which will ensure the consistency of the database states. Simply with Transactions the database can be role back to the initial state where it was before the deduction query executed on the database. Its like this.

  1. Transaction Start
  2. Deduct XXX amount form Bobs account.
  3. Add XXX amount for Alices account.
  4. If both queries run successfully then commit the changes
  5. Otherwise role back to the initial state.
For these operations Mysql provide several commands with it and lets see how we can implement that with PHP.

For support Mysql transactions PHP 5.0 and above provides set of methods which are very similar to the normal mysql functions but with an additional "i" letter with them. The most important functions out of them are as follows.

  • mysqli_connect() - connect with mysql
  • mysqli_select_db() - select a database
  • mysqli_autocommit() - enable and disable the auto commit option
  • mysqli_query() - run the mysql query
  • mysqli_rollback() - role back the database to the initial status
  • mysqli_commit() - commit all the changes to the database
  • mysqli_close() - close the mysql connection
Lets look at how you implement a transaction as a solution for the above problem.

Since transaction only supports from InnoDB storage engine you have to make sure all the database table are with InnoDB engine in your database.


$host = 'localhost';
$user = 'username';
$password = 'password';
$db = 'transaction';

$con = mysqli_connect($host, $user, $password);
mysqli_select_db($con, $db);

//Cancel auto commit option in the database
mysqli_autocommit($con, FALSE);

//You can write your own query here
$query1 = "query for deduct XXX amount form Bobs account";
$results[] = mysqli_query($con, $query1);

//You can write your own query here
$query2 = "query for add XXX amount for Alices account";
$results[] = mysqli_query($con, $query2);
$sucess = true;

foreach( $results as $result) {
if(!$result) {
$sucess = false;
}
}

if(!$sucess) {
mysqli_rollback($con);
} else {
mysqli_commit($con);
}
mysqli_close($con);

In above code the changes will done temporary because we have disabled the auto commit option in the database. After the two queries executed it will check for the results of those queries. If some thing went wrong with the database connection in the middle of the operations the changes will not be permanently applied to the database. And at the end it checks for the success of all queries and if all went fine it will commit the changes to the database.

With this code you will be able to make a consistent database operation for the money transfer action in your database. So your done with set of great consistent database operations on your database with PHP and Mysql.

Still Mysql allows only few operations such as update, insert and delete to be role back using its "Transactions". Following operations cannot be rolled back using Mysql.

  • CREATE DATABASE
  • ALTER DATABASE
  • DROP DATABASE
  • CREATE TABLE
  • ALTER TABLE
  • DROP TABLE
  • RENAME TABLE
  • TRUNCATE TABLE
  • CREATE INDEX
  • DROP INDEX
  • CREATE EVENT
  • DROP EVENT
  • CREATE FUNCTION
  • DROP FUNCTION
  • CREATE PROCEDURE
  • DROP PROCEDURE
You have to be aware on these limitations before you use "Transactions" for your application. Have a great time with Mysql "Transactions".

References :