Optimizing PHP objects
By Justin Silverton
The following tips can help in optimizing object-orientated PHP.
1. Initialise all variables before use.
2. Dereference all global/property variables that are frequently used in a method and put the values in local variables if you plan to access the value more than twice.
3. Try placing frequently used methods in the derived classes.
Warning: as PHP is going through a continuous improvement process, things might change in the future.
More Details
I have found that calling object methods (functions defined in a class) are about twice as slow as a normal function calls. To me that’s quite acceptable and comparable to other OOP languages.
Inside a method (the following ratios are approximate only):
1. Incrementing a local variable in a method is the fastest. Nearly the same as calling a local variable in a function.
2. Incrementing a global variable is 2 times slow than a local var.
3. Incrementing a object property (eg. $this->prop++) is 3 times slower than a local variable.
4. Incrementing an undefined local variable is 9-10 times slower than a pre-initialized one.
5. Just declaring a global variable without using it in a function also slows things down (by about the same amount as incrementing a local var). PHP probably does a check to see if the global exists.
6. Method invocation appears to be independent of the number of methods defined in the class because I added 10 more methods to the test class (before and after the test method) with no change in performance.
7. Methods in derived classes run faster than ones defined in the base class.
8. A function call with one parameter and an empty function body takes about the same time as doing 7-8 $localvar++ operations. A similar method call is of course about 15 $localvar++ operations.
20 Comments so far
Leave a reply






Interresting stuff. How did you measure these?
I’ve done similar tests myself. In order to time them, I would usualy place the code to test within a loop and execute it at least 1000 time to get a good test. Before and after the loop, simply call the php function microtime and store the result in a variable. The difference between the two is the time it took to execute all 1000 times. Divide by 1000 and you get the average time.
I think the better way to optimize is to use design patterns.
http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29
I used the pear framework package for benchmarking
http://pear.php.net/package/benchmark/redirected
I’m afraid I don’t agree with this advise.
I was not able to find any significant difference between calling a method in a base class or a subclass.
In my tests in PHP 5.1.2, a method call is only 30% slower than a function call.
Interestingly, the speed of a method call with no parameters was almost exactly the speed of a function call with one parameter. This is to be expected because the object is a hidden parameter to the method, which becomes the $this variable. Favoring functions over methods is a false optimization if your function would require one more parameter than the method.
The speed of incrementing is largely irrelevant to the overall speed of a PHP program. Generally, your performance problems lie elsewhere (database, IO, and includes).
I don’t know what to make of the variable initialization claim, except to say that this is irrelevant as a contributer to performance problems in PHP programs. I did not investigate this one.
The statement global $test actually creates a reference to the global variable. If you var_dump($GLOBALS), you will see the variable created if it does not already exist, even if you don’t assign it a value.
Don’t perturb your program design in the name of tiny or misleading performance gain. You will only gain a fraction of a percentage of execution time, if you don’t actually end up making the program slower. However, you loose many more units of maintainability. First, write the program to be correct and maintainable. Then, if the program is slow, profile it and look for opportunities to improve it.
See also Flawed Microbenchmarks.
The link you mentioned offers almost no information.
(http://www.procata.com/blog/archives/2005/02/24/flawed-microbenchmarks/)
If you want to plug your own blog…just tell us.
I agree with your statement about designing your applications with maintainability in mind.
Unless you are creating a massive application that is loading an insane ammount of objects and files, this does seem like it will cause more problems in the long run.
Like Jeff said, look at your IO to speed stuff up. Are your queries optimized? Are you including one large file, or smaller one’s as needed?
I’ve sped up pages 100% by optimizing queries and breaking out a massive include file. I think the most usefull part is declaring variables.
I agree with Jeff. think that while this advice may be true, it is not very helpful. Tuning the kind of variable initialisation and other minor tweaks might possibly speed up your app by 2% overall if you applied them everywhere (possibly thousands of code changes which could introduce errors). Using a PHP optimiser/accelerator will often get you 500% without having to touch your code, and in more complex systems, a shared object cache like memcached can give even more. You also failed to mention MySQL’s excellent query cache which can make a huge difference to query times.
Microbenchmarking with tools like pear’s benchmarker is all very well, but it doesn’t identify bottlenecks in your application, which are usually at the design pattern level. You’d be much better off using xdebug’s profiler before taking any of the advice here - in my own profiling I’ve often found that object initialisation is slower than database queries!
@Eugene Panin: I’d not think design patterns to be a great way to boost performance: it seems to me to be more of a design or architectural optimization, not performance.
M.T.
PHP OO is a dog. Don’t use it.
Here are some actual benchmarks:
http://destiney.com/benchmarks
everyone who posted comments here are under the impression that I am saying these are the end-all and be-all of optimizations.
Yes, I realize that there are many other things you can do, I was merely pointing some things out that can help you squeeze out that last bit of performance from your code.
Here are a couple of responses to comments: “You also failed to mention MySQL’s excellent query cache which can make a huge difference to query times”.
I do recommend (and use) using opcode optimizers such as zend or ion cube because they can help speed up execution time. If we’re going to go that route, glib compression is a good way to go as well.
as for mysql query caching, it will work well for one server but does not scale over mass amounts of servers. For multiple servers,
I would use memcached: http://www.danga.com/memcached/
“Microbenchmarking with tools like pear’s benchmarker is all very well, but it doesn’t identify bottlenecks in your application, which are usually at the design pattern level. You’d be much better off using xdebug’s profiler before taking any of the advice here - in my own profiling I’ve often found that object initialisation is slower than database queries!”
These fixed aren’t going to help with complete design flaws or database queries. I thought by not mentioning those, I made it pretty clear.
Thanks for the site Greg.
A rule about comments and moderation: I will not tolerate insults or other comments of this sort on the jaslabs site. I do understand people might have opinions about my articles, but when you insult me, my profession, this site, or the way I do things, you are just asking to get your comments removed.
I welcome other people’s viewpoints. But please keep them constructive.
Greg/others: So OO shouldn’t be used because it’s slower than functional programming? Have you ever created a larger system?
Never optimize anything - *unless* you have serious bottlenecks, in which case you optimize after you’ve implemented the solution the correct way - becuase then you know what tradeoffs you’ll have to make to optimize it.
- Bjorn
Please feel free to go directly to the article I linked to on Flawed Benchmarks. The point being that many times micro-benchmarks don’t measure what we think they are measuring and that time spent concentrating on the micro performance issues would be better spent on real performance issues. Its called prioritization and opportunity cost.
Sorry Greg, but, the OO benchmarks at http://destiney.com/benchmarks are a good example of bad benchmarks. These benchmarks set up a straw man by picking a nonsense task, and implementing it in a way in OO that no-one would actually do. I can show that anything is faster than anything with this technique.
OO used properly is not significantly slower than code that avoids objects. That is the point I wanted to get across with my comments here.
Remember, there is no significant difference in performance between:
$obj->method();and
func($data);Its only when you compare
$obj->method();with
func();that you get a difference, but really that is comparing apples and oranges. Taking micro benchmarks out of context and trying to draw macro conclusions about what is faster is exactly the kind of thing that I’m saying watch out for.
Any reason why methods in derived classes run faster than ones defined in the base class?
Great post, very useful for my own coding.
class a
{
var $somevar;
}
class b extends a
{
}
$object= new a;
$object->somevar=”I’m a var”;
$newobject = new b;
echo $object->somevar; // Works
echo $newobject>somevar; // Doesn’t work. Why? How to make it work?
This won’t work because your objects instances are not connected in any way, but their definitions are.
So,
for this to work: echo $newobject->somevar;
you first need to initialize it with a variable such as $newobject->somvar = 5;
[…] Jaslabs » Optimizing PHP objects […]