Performance of static methods and functions

In PHP (unlike what I originally thought), there are overheads of calling static methods versus simple functions.

On a very simple stand, the costs account for more than 30% of the call time (the method simply returns a 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 that the actual time is still negligible, unless I call something a million times, but the fact is that it is.

Anyone want to try to explain what is going on behind the scenes?

Update:
- added object method stand

+56
performance oop php
Sep 24 '09 at 16:15
source share
7 answers

Apparently, this point was fixed in later versions of PHP (5.5.12).

I ran the OP code (with empty methods) and I get the following results:

 Static Time: 1.0153820514679 ms Object Time: 1.100515127182 ms 

Edit: eight months and a few releases later ...

It is interesting to see how Zend and the community are actively working on PHP performance.

🐘 PHP 5.6

Here are the same tests 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 also compiled PHP 7.0 alpha 1 (ZE 3.0), and it's amazing to see how fast a language such as PHP (compared to other dynamic languages, as you can see here or here ) can be optimized over and over again:

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

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

Edit, October 2015 a year later: PHP 7.0 RC5 . Now "static time" is faster. It is important to note: a scalar type hint (a new function in PHP7) brings significant overhead, it is about 16% slower (the type of hint does not make your code 16% slower, it's slower when you code only consists of function calls;) In real applications it is insignificant). Such overhead may seem counterintuitive, but it is less unexpected when you know that dynamic typing is at the core of PHP. Unlike other more static languages, the hint type in PHP means more checks for the Zend Engine, and no less than some of us can expect. In the future, we are likely to get more optimizations at runtime (just like analyzing the HHVM runtime code and the JiT approach). Keep in mind that PHP7 is young, and all the cleanup that has been done for this release will improve features and performance in the future.

🐘 HHVM

The test against HHVM 3.7.1 still shows that HHVM easily wins in such tests, here you can see the advantages of compiling JiT (JiT is a "planned" function for future versions of PHP, we will probably get it in branches 7.x or 8.x. Zend created PoC as an extension to OpCache ):

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

For HHVM, functions and static methods have very similar synchronization, this may allow us to think that they are almost the same inside (after all, a static method is very similar to a function with names). Instance instance is "catastrophic" compared to others. This shows how the HHVM and ZE are very different engines.

Conclusion

There is no guarantee that one of these methods (static / instance) will stay faster forever. Use what seems best from a software development point of view and keep consistent code in an existing application.

If you have a choice and / or if you are writing a library, etc., perhaps you can use instance methods that are more friendly to DI environments, and this gives more control to the developer who consumes your API.

If you just provide utility functions (for example, these small packages in the npm ecosystem), you can use functions with names (but keep in mind that PHP still doesn’t work; there is an autoload function , which means that Composer cannot be lazy loading your library , as is the case with PSR-0/4)

+53
Oct. 27 '14 at 16:17
source share

There was a large penalty when invoking the static method, but it was fixed in 5.4.0 - see extensive test results at http://www.micro-optimization.com/global-function-vs-static-method .

+23
Dec 07
source share

I repeated the test on my car several times and surprisingly you are right!

In PHP, methods for invoking a static class seem slower than methods for invoking objects. Click here for a simple test.

The code with the current test is in the link above.

I even tried to put both the objet method and the static method in the same class, and the static method still calls SLOWER !!!

At this point, I wonder how slow the invocation of the static method of the inherited class can be, since inheritance adds delay.

Unfortunately, I do not know why. PHP may be taking longer to find a static method definition.

As a side note, I could only say that in a real application an object is usually created that was created before calling one of its methods. Therefore, your test should take this into account when comparing a static call loop with a loop that each time (or at least several times) [*] creates an object:

 for($i=0; $i<10*1000*1000; $i++) { $someObj = new someObj(); $someObj->doTest($i); } 

obviously slower than calling static .

 for($i=0; $i<10*1000*1000; $i++) { SomeClass::doTest($i); } 



[*] The problem is this: how many times several times to simulate what is happening in a real world application? Hard to say!

+7
Aug 12 '11 at 8:01 a.m.
source share

There is something wrong with your tests. Using a website designed to work with multiple users, you must create an object for each of them. To run this object method in your tests, you must:

 for($i=0; $i<10*1000*1000; $i++) { $someObj = new someObj(); $someObj->doTest($i); } 

If your object has more properties and methods, then its creation is slower, and PHP uses more memory. The static method will not have this problem, and therefore the use of static methods is the best choice in many situations. For example, a class with some convenient tools with static methods for common tasks.

+6
Sep 05 '12 at 14:50
source share

It has been a while since I made any kind of PHP, but it probably looks like what you would expect in other programming environments.

The static method probably requires some construction of the SomeClass object behind the scenes each time it is called, while the function can be executed without any cost to run. Creating an object can be expensive depending on a number of things: destruction of existing objects by the garbage collector / counter, causing memory fragmentation, caused by fragmentation, suboptimal memory allocation policies in the C runtime, etc.

It would be interesting to compare the effectiveness of the existing object method. To do this, create an instance of SomeClass and call the instance method again.

+2
Sep 24 '09 at 16:30
source share

In the case of a static method, PHP must check whether the method can be called or cannot be called from the call context (public, protected, private). This is most likely what causes the overhead, or at least part of it, since a classic function call does not require PHP to perform such a check.

+2
Sep 24 '09 at 16:49
source share

I follow what Morgan Touverey Quilling did, but with PHP 7. Is there 3 iterations done if it takes longer for the first run than for the subsequent ones. Includes all classes, how this can be done realistically. All included files simply return input.

 include 'lib/global.php'; include 'SomeClass.php'; include 'StaticTest.php'; $someObj = new SomeClass(); $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) StaticTest::doStaticTest($i); echo "<br>Static Time: " , (microtime(true)-$starttime) , " ms\n"; // bench object method $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) $someObj->doObjTest($i); echo "<br>Object Time: " , (microtime(true)-$starttime) , " ms\n"; // bench function $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) something_doTest($i); echo "<br>Function Time: " , (microtime(true)-$starttime) , " ms\n"; echo "<br>Static Time: " , (microtime(true)-$starttime) , " ms\n"; // bench object method $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) $someObj->doObjTest($i); echo "<br>Object Time: " , (microtime(true)-$starttime) , " ms\n"; // bench function $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) something_doTest($i); echo "<br>Function Time: " , (microtime(true)-$starttime) , " ms\n"; echo "<br>Static Time: " , (microtime(true)-$starttime) , " ms\n"; // bench object method $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) $someObj->doObjTest($i); echo "<br>Object Time: " , (microtime(true)-$starttime) , " ms\n"; // bench function $starttime = microtime(true); for ($i = 0; $i< 10*100000; $i++) something_doTest($i); echo "<br>Function Time: " , (microtime(true)-$starttime) , " ms\n"; 

Just note that this is done on one of my web hosts, as it’s easier to switch php versions, so there might be some noise.

PHP 7.0.33

 Static Time: 0.14076709747314 ms Object Time: 0.16203689575195 ms Function Time: 0.13194108009338 ms Static Time: 0.13194918632507 ms Object Time: 0.1779100894928 ms Function Time: 0.13044309616089 ms Static Time: 0.13045001029968 ms Object Time: 0.16074585914612 ms Function Time: 0.13029479980469 ms 

PHP 7.1.29

 Static Time: 0.13407206535339 ms Object Time: 0.13267111778259 ms Function Time: 0.1302649974823 ms Static Time: 0.13027906417847 ms Object Time: 0.1390438079834 ms Function Time: 0.16873598098755 ms Static Time: 0.16874289512634 ms Object Time: 0.13901305198669 ms Function Time: 0.12576103210449 ms 

PHP 7.2.18:

 Static Time: 0.1657600402832 ms Object Time: 0.15700101852417 ms Function Time: 0.1484169960022 ms Static Time: 0.14842295646667 ms Object Time: 0.16168689727783 ms Function Time: 0.17508292198181 ms Static Time: 0.17508983612061 ms Object Time: 0.19771790504456 ms Function Time: 0.1468551158905 ms 

PHP 7.3.5

 Static Time: 0.10701704025269 ms Object Time: 0.097011089324951 ms Function Time: 0.075740098953247 ms Static Time: 0.07575798034668 ms Object Time: 0.083790063858032 ms Function Time: 0.072473049163818 ms Static Time: 0.072479009628296 ms Object Time: 0.081503868103027 ms Function Time: 0.071882963180542 ms 

PHP 7.2 was much slower than other versions on average. I found the smallest number, but it also reached .2 ####. I do not have 7.4 at the moment.

0
Jun 06 '19 at 22:33
source share



All Articles