Pages

Sunday, April 28, 2013

PHP Performance Tips

Note this!!

-- begin --

Loops are evil

We habitually use loops. They are powerful programming tools, but they can frequently cause bottlenecks. One slow operation executed once is one problem, but if this sentence is inside a loop, the problem is magnified. So, are loops bad? No, of course not, but you need to assess your loops carefully, especially nested loops, to avoid possible problems.

Take the following code as an example: 

01.<?php
02. 
03.// bad example
04. 
05.function expexiveOperation() {
06. 
07.sleep(1);
08. 
09.return "Hello";
10. 
11.}
12. 
13. 
14. 
15.for ($i=0; $i<100; $i++) {
16. 
17.$value = expexiveOperation();
18. 
19.echo $value;
20. 
21.}

This code works, but it is obvious that you are setting the same variable once per cycle.

01.<?php
02. 
03.// better example
04. 
05.function expexiveOperation() {
06. 
07.sleep(1);
08. 
09.return "Hello";
10. 
11.}
12. 
13. 
14. 
15.$value = expexiveOperation();
16. 
17.for ($i=0; $i<100; $i++) {
18. 
19.echo $value;
20. 
21.}

In this code, you can detect the problem and easily refactor. However, real life might not be this simple.

To detect performance problems, consider the following:

 

●      Detect big loops (for, foreach, ...)

●      Do they iterate over a big amount of data?

●      Measure them.

●      Can you cache the operation inside the loop?

○      If yes, what are you waiting for?

○      If not, mark them as potentially dangerous and focus your inspections on them. Small performance problems in your code can be multiplied.

 

Basically, you must know clearly where are your big loops are and why. It is difficult to memorize all the source code of your applications, but you must be aware of the potentially expensive loops. Yes, I know. This recommendation seems to be written with micro-optimization in mind (like: cache the result of count()) but it isn't. Sometimes I need to refactor old scripts with performance problems. I normally use the same pattern: Find loops with the profiler and refactor the heaviest.

We have one good friend here to help us with this job: The profiling tools. Xdebug and Zend Debuggerallow us to create profiling reports. If we choose Xdebug we can also use Webgrind, a web front-end for Xdebug. Those reports can help us detect bottlenecks. Remember, a bottleneck is a problem, but a bottleneck iterated 10000 times is 10000x bigger. It seems obvious, but people tend to forget.


-- end --