- 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.
- Try to use as much caching as possible, typically I would use this configuration:
Squid -- PHP and memcache or file caching -- Database. - 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.
- Compile PHP with the "configure –-enable-inline-optimization" option to generate the fastest possible PHP executable.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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).
- Optimize your loops first. Move loop invariants (constants) outside the loop.
- Use the array and string functions where possible. They are faster than writing equivalent code in PHP.
- 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.
- 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.
- 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.
- 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().
- 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.
- For processing XML, parsing with regular expressions is significantly faster than using DOM or SAX.
- Unset() variables that are not used anymore to reduce memory usage. This is mostly useful for resources and large arrays.
- 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.
- 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.
I gave a talk on performance optimization few years back at PHP - http://www.slideshare.net/jignesht/performance-tuning-in-php-presentation
ReplyDeleteThough it's little older, but many things are still valid :)