CHAPTER 14 – OPTIMIZING CODE – Rewrite in C
Sometimes, it is just not possible to optimize a piece of PHP code. The code is as fast as it possibly can be in PHP, but it may still be a bottleneck. This is the time to wield your axe, chop it to bits, and rewrite it in C as a PHP extension. If you have some C skills, it's not that hard. Consult Chapter 15, "An Introduc- tion to Writing PHP Extensions," for examples.
Versus Procedural Code PHP has the advantage of not forcing a particular coding style. You can write 100 percent procedural code, or you can go all object-oriented. Most likely, you are going to end up writing code that is somewhere in between procedural and object-oriented, because most of the functionality provided by PHP's bundled extensions is procedural, while PEAR offers OOP interfaces. From a performance point of view, procedural code is slightly faster. The following example shows another micro-benchmark that compares the perfor- mance difference between regular function calls and method calls: <?php require 'ubm.php'; class Adder { function add2($a, $b) { return $a + $b; } function add3($a, $b, $c) { return $a + $b; } } function adder_add2($a, $b) { return $a + $b; } function adder_add3($a, $b) { return $a + $b; } function run_oo_bm2($count) { $adder = new Adder; for ($i = 0; $i < $count; $i++) $adder->add2(5, 7); } function run_oo_bm3($count) { $adder = new Adder; for ($i = 0; $i < $count; $i++) $adder->add2(5, 7, 9); } function run_proc_bm2($count) { for ($i = 0; $i < $count; $i++) adder_add2(5, 7); } function run_proc_bm3($count) { for ($i = 0; $i < $count; $i++) adder_add3(5, 7, 9); } $loops = 1000000; micro_benchmark("proc_2_args", "run_proc_bm2", $loops); micro_benchmark("proc_3_args", "run_proc_bm3", $loops); micro_benchmark("oo_2_args", "run_oo_bm2", $loops); micro_benchmark("oo_3_args", "run_oo_bm3", $loops); Figure 14.16 shows the result.
Fig. 14.16 Performance comparison of method and function calls with two or three parameters. Here, function calls are 1112 percent faster than method calls with both two and three arguments. Keep in mind that this micro-benchmark only measures the overhead caused by the actual function call (looking up the function/method name, pass- ing parameters, returning a value). This will be a performance factor if your code has many small functions, which makes the call overhead account for a larger portion of the total execu- tion time.
SUMMARY High-performance web-application design and performance tuning is a large and complex subject that could fill up a book on its own. This chapter focused on performance-related issues in PHP 5, taking you from the design process to profiling, benchmarking, and caching techniques. Learning about the approaches that work and are not for big sites is time-consuming, but don't give up! The two key things to remember are to strive toward a lean, effective, and elegant design, and to relentlessly profile and benchmark your code.