Skip to main content

Optimizing PHP


  1. The more you understand the software you are using (Apache, PHP, IIS, your database) and the deeper your knowledge of the operating system, networking and server hardware, the better you can perform global optimizations on your code and your system.
  2. Try to use as much caching as possible, typically I would use this configuration:
    Squid -- PHP and memcache or file caching -- Database.
  3. For PHP scripts, the most expensive bottleneck is normally the CPU. If you are not getting out of memory messages, more CPUs are probably more useful than more RAM.
  4. Compile PHP with the "configure –-enable-inline-optimization" option to generate the fastest possible PHP executable.
  5. Tune your database and index the fields that are commonly used in your SQL WHERE criteria. ADOdb, the very popular database abstraction library, provides a SQL tuning mode, where you can view your invalid, expensive and suspicious SQL, their execution plans and in which PHP script the SQL was executed.
  6. Use HTML caching if you have data that rarely changes. Even if the data changes every minute, caching can help provided the data is synchronized with the cache. Depending on your code complexity, it can improve your performance by a factor of 10.
  7. Benchmark your most complex code early (or at least a prototype), so you get a feel of the expected performance before it is too late to fix. Try to use realistic amounts of test data to ensure that it scales properly.Updated 11 July 2004: To benchmark with an execution profile of all function calls, you can try the xdebug extension. For a brief tutorial of how i use xdebug, seesqueezing code with xdebug. There are commercial products to do this also, eg. Zend Studio.
  8. Consider using a opcode cache. This gives a speedup of between 10-200%, depending on the complexity of your code. Make sure you do some stress tests before you install a cache because some are more reliable than others.
  9. Use ob_start() at the beginning of your code. This gives you a 5-15% boost in speed for free on Apache. You can also use gzip compression with ob_gzhandler() for extra fast downloads (this requires spare CPU cycles) - Updated 30 Oct 2009.
  10. Consider installing Zend Optimizer. This is free and does some optimizations, but be warned that some scripts actually slow down when Zend Optimizer is installed. The consensus is that Zend Optimizer is good when your code has lots of loops. Today many opcode accelerators have similar features (added this sentence 21 Oct 2003).
  11. Optimize your loops first. Move loop invariants (constants) outside the loop.
  12. Use the array and string functions where possible. They are faster than writing equivalent code in PHP.
  13. The fastest way to concatenate multiple small strings into one large string is to create an output buffer (ob_start) and to echo into the buffer. At the end get the contents using ob_get_contents. This works because memory allocation is normally the killer in string concatenation, and output buffering allocates a large 40K initial buffer that grows in 10K chunks. Added 22 June 2004.
  14. Pass objects and arrays using references in functions. Return objects and arrays as references where possible also. If this is a short script, and code maintenance is not an issue, you can consider using global variables to hold the objects or arrays.
  15. If you have many PHP scripts that use session variables, consider recompiling PHP using the shared memory module for sessions, or use a RAM Disk. Enable this with "configure -–with-mm" then re-compile PHP, and set session.save_handler=mm in php.ini.
  16. For searching for substrings, the fastest code is using strpos(), followed by preg_match() and lastly ereg(). Similarly, str_replace() is faster than preg_replace(), which is faster than ereg_replace().
  17. Added 11 July 2004: Order large switch statements with most frequently occuring cases on top. If some of the most common cases are in the default section, consider explicitly defining these cases at the top of the switch statement.
  18. For processing XML, parsing with regular expressions is significantly faster than using DOM or SAX.
  19. Unset() variables that are not used anymore to reduce memory usage. This is mostly useful for resources and large arrays.
  20. For classes with deep hierarchies, functions defined in derived classes (child classes) are invoked faster than those defined in base class (parent class). Consider replicating the most frequently used code in the base class in the derived classes too.
  21. Consider writing your code as a PHP extension or a Java class or a COM object if your need that extra bit of speed. Be careful of the overhead of marshalling data between COM and Java.



Useless Optimizations
Some optimizations are useful. Others are a waste of time - sometimes the improvement is neglible, and sometimes the PHP internals change, rendering the tweak obsolete.
Here are some common PHP legends:
a. echo is faster than print
Echo is supposed to be faster because it doesn't return a value while print does. From my benchmarks with PHP 4.3, the difference is neglible. And under some situations, print is faster than echo (when ob_start is enabled).
b. strip off comments to speed up code
If you use an opcode cache, comments are already ignored. This is a myth from PHP3 days, when each line of PHP was interpreted in run-time.
c. 'var='.$var is faster than "var=$var"

This used to be true in PHP 4.2 and earlier. This was fixed in PHP 4.3. Note (22 June 2004): apparently the 4.3 fix reduced the overhead, but not completely. However I find the performance difference to be negligible.

Comments

  1. I gave a talk on performance optimization few years back at PHP - http://www.slideshare.net/jignesht/performance-tuning-in-php-presentation

    Though it's little older, but many things are still valid :)

    ReplyDelete

Post a Comment

Popular posts from this blog

UpComing Features in PHP 5.3

Namespaces A subject touched and trialed many times in PHP, namespaces. This feature has been responsible for the longest discussions on PHP-DEV, but finally a consensus has arrived on how this is going to work. The biggest benefit namespaces will provide is shortening of long classnames. To make sure that your class libraries can plug into foreign code, it has always been recommended to prefix your classes, for example "Zend_DB_Connection". This can however lead to very long names. Namespaces fixes this by grouping classes together. The full-on classname becomes Zend::DB:Connection, and by placing 'use Zend::DB' on top of your code, the 'Connection' class can be referenced with just that name. Example: // The class file namespace Zend :: DB ; class Connection { function foo () { echo 'bar' ; } } ?> require 'Zend/DB/Connection.php' ; use Zend :: DB :: Connection ; $connection = new Connection (); $connection -> foo (); ?

Install PHP 5.3.0/Lighttpd On Debian (Lenny) With Imap, MySQL, Sqlite3 And ImageMagick Support

Install PHP 5.3.0/Lighttpd On Debian (Lenny) With Imap, MySQL, Sqlite3 And ImageMagick Support This tutorial covers the setup of PHP 5.3.0/Lighttpd on Debian (lenny) with imap, mysql, mysqli, sqlite3, ImageMagick and mycrypt support. For this tutorial I will assume you are logged in as root this is not advised. First we need to install the webserver: aptitude install lighttpd Now we install the packages needed for mysql and mysqli support. You will be promoted to enter a mysql root password - please use a strong password. aptitude install mysql-server mysql-client libmysqlclient15-dev Next install some packages php needs to compile. aptitude install libtidy-dev curl libcurl4-openssl-dev libcurl3 libcurl3-gnutls zlib1g zlib1g-dev libxslt1-dev libzip-dev libzip1 libxml2 libsnmp-base libsnmp15 libxml2-dev libsnmp-dev libjpeg62 libjpeg62-dev libpng12-0 libpng12-dev zlib1g zlib1g-dev libfreetype6 libfreetype6-dev libbz2-dev libxpm-dev libmcrypt-dev libmcrypt4 sqlite3 bzip2 build-essential l

Zend Framework WebServices

REST Web Services use service-specific XML formats. These ad-hoc standards mean that the manner for accessing a REST web service is different for each service. REST web services typically use URL parameters (GET data) or path information for requesting data and POST data for sending data. Zend Framework provides both Client and Server capabilities, which, when used together allow for a much more "local" interface experience via virtual object property access. The Server component features automatic exposition of functions and classes using a meaningful and simple XML format. When accessing these services using the Client, it is possible to easily retrieve the return data from the remote call. Should you wish to use the client with a non-Zend_Rest_Server based service, it will still provide easier data access. In addition to Zend_Rest_Server and