Performance of static methods vs. functions

前端 未结 7 750
盖世英雄少女心
盖世英雄少女心 2020-11-29 21:50

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 th

相关标签:
7条回答
  • 2020-11-29 22:34

    I repeated the test on my machine multiple times and surprisingly you are right!

    In PHP calling methods of static class seems to be slower than calling object methods. Click here for simple test.

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

    I even tried placing both the objet method and the static method in the same class and the static method still results SLOWER!!!

    At this point I'm wondering how slow could be a call to a static method of an inherited class, since inheritance adds up delay.

    Sadly, I'm clueless about the reason. Maybe PHP takes more time in finding the definition of the static method.

    As a side note I could only say that in a real life application it usually happens to have the object created before calling one of its methods. Therefor your test should take this into account comparing the loop of static calls to a loop that each time (or at least some times) [*] creates the objet:

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

    thus is obviously slower than the static call.

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

    [*] the problem is: how much is some times in order to simulate what happnes in a real world app? It's hard to say!

    0 讨论(0)
  • 2020-11-29 22:35

    I am following up what Morgan Touverey Quilling did but with PHP 7. Did 3 iterations incase it takes longer for the first run vs subsequent runs. Includes all classes as it might be done realistically. All included files just return the 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 being done on one of my webhosts as its easier to switch php versions so 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 seemed to run a lot slower than the other versions on average. I found their lowest number but it got into the low .2####'s too. Don't' have 7.4 as of right now.

    0 讨论(0)
  • 2020-11-29 22:36

    There is some thing Wrong in your tests. With a website designed to work with multiple users at the same time you have to create an object for each one. To run that object's method in your tests you should have:

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

    If your object had more properties and methods then creating it is slower and PHP uses more memory. A static method won't have this problem, and therefore using static methods is a better choice in lots of situations. For example, a class with some handy tools with static methods for common tasks.

    0 讨论(0)
  • 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 .

    0 讨论(0)
  • 2020-11-29 22:47

    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.

    0 讨论(0)
  • 2020-11-29 22:50

    In the case of the static method, PHP has to check wether the method can or cannot be called from the calling context (public, protected, private). That's most likely what causes the overhead, or at least part of it, since the classic function call doesn't require PHP to perform that kind of check.

    0 讨论(0)
提交回复
热议问题