Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance of static methods vs. functions

In PHP, (unlike what I originally thought) there is an overhead of calling static methods vs simple functions.

On a very simple bench, the overhead is over 30% of the calling time (the method just returns the parameter):

// bench static method $starttime = microtime(true); for ($i = 0; $i< 10*1000*1000; $i++)     SomeClass::doTest($i);  echo "Static Time:   " , (microtime(true)-$starttime) , " ms\n";  // bench object method $starttime = microtime(true);  for ($i = 0; $i< 10*1000*1000; $i++)     $someObj->doTest($i);  echo "Object Time:   " , (microtime(true)-$starttime) , " ms\n";  // bench function $starttime = microtime(true);  for ($i = 0; $i< 10*1000*1000; $i++)     something_doTest($i);  echo "Function Time: " , (microtime(true)-$starttime) , " ms\n"; 

outputs:

Static Time:   0.640204906464 ms Object Time:   0.48961687088 ms Function Time: 0.438289880753 ms 

I know the actual time is still negligible unless I am actually calling something 1 million times, but the fact is that its there.

Will anyone care to try and explain what is happening behind the scenes?

update:
- added object method bench

like image 868
J.C. Inacio Avatar asked Sep 24 '09 16:09

J.C. Inacio


People also ask

Does static method improve performance?

Static methods are faster but less OOP. If you'll be using design patterns, static method is likely bad code. Business logic are better written as non-Static. Common functions like file reading, WebRequest etc are better as static.

Are static methods faster Java?

As expected, virtual method calls are the slowest, non-virtual method calls are faster, and static method calls are even faster.

Why static method should be avoided?

Static methods are bad for testability. Since static methods belong to the class and not a particular instance, mocking them becomes difficult and dangerous.


2 Answers

There used to be a big penalty when calling a static method - but it's fixed in 5.4.0 - see the extensive test results http://www.micro-optimization.com/global-function-vs-static-method .

like image 40
Greg Avatar answered Oct 22 '22 14:10

Greg


Apparently this point has been fixed in later versions of PHP (5.5.12).

I ran the OP's code (with empty methods), and I get these results :

Static Time:   1.0153820514679 ms Object Time:   1.100515127182 ms 

Edit: Eight months and some releases later...

It's interesting to see how Zend and the community are working hard on PHP's performance.

🐘 PHP 5.6

Here is the same benchmark with PHP 5.6.9 (ZE 2.6) :

Static Time:   0.97488021850586 ms Object Time:   1.0362110137939 ms Function Time: 0.96977496147156 ms 

For one run, "object time" was even faster than static time, so now they are very close. Better, we can see that objects are almost fast as functions!

🐘 PHP 7.0

I've also compiled PHP 7.0 alpha 1 (ZE 3.0) and it is amazing to see how a fast language like PHP (Compared to other dynamic languages as you can see here or here) can be optimized again and again:

Static Time:   0.33447790145874 ms Object Time:   0.30291485786438 ms Function Time: 0.2329089641571 ms 

With PHP7, basic functions have been greatly optimized, and "static time" is again slower than "instance/object time".

Edit, October 2015 one year later : PHP 7.0 RC5. Now, "static time" is faster. An important thing to note: scalar type hinting (new feature in PHP7) brings a significant overhead, it's about 16% slower (type hinting does not make your code 16% slower, it's that slower when you code is only composed of function calls ;) In real life applications, this is negligible). Such an overhead could seem illogic, but it's less surprizing when you know that dynamic typing is at the core of PHP. Contrarily to other more-static languages, type hinting in PHP means more checks for the Zend Engine, and not less as some of us could expect. In the future, we will probably get more runtime optimizations on this point (exactly like HHVM's runtime code analyses and JiT approach). Do not forget that PHP7 is young, and all the cleanup that has been done for this release permits great enhancements in the future, in features and performance.

🐘 HHVM

A test against HHVM 3.7.1 still shows that HHVM easily wins on that type of benchmarks, here you can see the benefits of a JiT compilation (JiT is a "planned" feature for future versions of PHP, we'll probably get it in the 7.x or 8.x branches. Zend had created a PoC, as an OpCache extension):

Static Time:   0.070882797241211 ms Object Time:   0.23940300941467 ms Function Time: 0.06760311126709 ms 

For HHVM, functions and static methods have a very similar timing, this could let us think that, internally, those are almost the same things (after all, a static method is very similar to a namespaced function). The instance timing is "catastrophic" compared to the others. This shows how HHVM and ZE are very different engines.

Conclusion?

There's no guarantee that one of these practices (static/instance) will stay the faster, forever. Use what seems the best in terms of software design and keep a coherent code into an existing application.

If you have the choice, and/or if you're writing a library, etc, then maybe you could use instance methods, it's more friendly with DI environments, and that gives more control to the developer that consumes your API.

If you're just providing utility functions (like those little packages in npm's ecosystem), then you could use namespaced functions (but be aware that PHP still doesn't have function autoloading, meaning that Composer can't lazy-load your library like it does with PSR-0/4)

like image 70
Morgan Touverey Quilling Avatar answered Oct 22 '22 14:10

Morgan Touverey Quilling