静态方法比非静态方法快吗?

时间:2011-01-24 08:25:35

标签: php performance object methods static

编辑::哦,我忘了

class Test1{
    public static function test(){
        for($i=0; $i<=1000; $i++)
            $j += $i;       
    }   
}

class Test2{
    public function test() {
        for ($i=0; $i<=1000; $i++){
            $j += $i;
        }
    }

}

此算法

$time_start = microtime();
$test1 = new Test2();
for($i=0; $i<=100;$i++)
    $test1->test();
$time_end = microtime();

$time1 = $time_end - $time_start;

$time_start = microtime();
for($i=0; $i<=100;$i++)
    Test1::test();
$time_end = microtime();    

$time2 = $time_end - $time_start;
$time = $time1 - $time2;
echo "Difference: $time";

我有结果

Difference: 0.007561 

而这些天,我试图让我的方法尽可能静态。但这是真的吗,至少对于PHP来说是

6 个答案:

答案 0 :(得分:34)

当您不需要方法周围的对象时,应始终使用静态,并在需要对象时使用动态。在您提供的示例中,您不需要对象,因为该方法不会与您的类中的任何属性或字段进行交互。

这个应该是静态的,因为它不需要对象:

class Person {
    public static function GetPersonByID($id) {
        //run SQL query here
        $res = new Person();
        $res->name = $sql["name"];
        //fill in the object
        return $res;
    }
}

这个应该是动态的,因为它使用它所在的对象:

class Person {
    public $Name;
    public $Age;
    public function HaveBirthday() {
        $Age++;
    }
}

速度差异很小,但您必须创建一个对象来运行动态方法,并且该对象保存在内存中,因此动态方法使用更多内存和更多时间。

答案 1 :(得分:17)

简短回答因为我不想咆哮太多:

它是否更快并不重要。如果你需要一些性能非常重要的东西,那你考虑每个函数调用的剃须量为0.02纳秒,而不管你是不是用PHP做的。

静态方法会产生不可测试的,不可维护的“全局所有”代码,这些代码对您的伤害远远超过其他任何东西。

如果你不想使用适当的OOP(如果你知道你做了什么以及为什么这样做,那就完全没问题了)那么请你这样做。只是不要这样做,因为你想节省CPU时间。

http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/

http://sebastian-bergmann.de/archives/885-Stubbing-Hard-Coded-Dependencies.html

http://en.wikipedia.org/wiki/Class-based_programming

如果您只点击一个链接: http://www.scribd.com/doc/20893084/Advanced-OOP-and-Design-Patterns#scribd

Premature optimization is the root of all evil.构建易于维护的代码,如果速度变慢,需要一个配置文件,它很可能会告诉你数据库中的文件系统是有问题的,你得到的所有内容都会有一些问题。非常具体的PHP片段来优化。如果你有干净,可更改的代码,你可以加快这些速度。

答案 2 :(得分:3)

&#34;过早优化是所有邪恶的根源&#34;被Donald Knuth称为 40年前。你知道,当你拥有英特尔发明的新的4004 微处理器时。那个鼓就像任何马一样难以击败,我看不出它与原始问题的关系。事实上,我可能很幸运,但我还没有看到这种猖獗行为的证据。唉,互联网上的某个人必须要在我们所有人都能进入夜晚之前做好准备。

关于主题的更多内容,我认为接受的答案是最实用的,对问题的第一个评论是正确的问题。静态与实例化代码的速度是否更快主要取决于语言的实现方式,而且我没有看到任何这些响应足以回答有关PHP的问题。谁知道PHP并想要权衡?

答案 3 :(得分:1)

一般来说,是的。静态方法和属性工作得更快(PHP 5.3除外)。

您可以参考这个或多或少详细的comparison of static and non-static methods in PHP

答案 4 :(得分:0)

如果您打算将方法设置为静态并添加一个参数来传递您的类对象,那实际上会更慢。我用这个测试基准测试,这是一个相当大的损失。通过各种静态方法传递对象是性能损失。在对象中保持动态更好。

我很确定动态方法的性能更快,因为调用是在同一个对象中进行的。在对象中使用静态方法时,每次调用都有一个额外的跳跃,因为调用不是在对象内进行的,而是在类中进行的。

它确实减少了使用静态方法的内存使用量。如果你可以在课堂上放置你的方法,那么没有它们的对象将会更轻。但最重要的是在我的测试中是可访问性。直接访问方法是最快的,而访问静态类方法是额外的跃点。这真的是处理与内存的问题。十分之九,动态更快。

答案 5 :(得分:0)

此处有类似问题:Does using static methods and properties in PHP use less memory?

我刚刚改进了斯坦尼斯拉夫链接的基准,使其能够正常运行:

https://3v4l.org/rDpVv

Results for PHP 7.4.1:

Runs by case: 500000 
Memory usage at start: 426,320

Run                                 Duration    %       Memory
Dynamic                             0.0594      30%     496
Dynamic instantiated                0.0917      46%     0           #
Dynamic instantiated stored         0.1994      100%    48,967,472  # slowest
Storage only                        0.0422      21%     16,781,392
Cost of instations only when stored 0.1572      79%     32,186,O8O  # cost of stored instatiations minus storage cost (diff of 2 previous lines)
Static                              0.0870      44%     0           # equivalent to dynamic with instantiation
Singletons with many getInstance    0.1213      61%     376
Singletons with one getInstance     0.0669      34%     320         # equivalent to "Dynamic"
Functions assigning $GLOBALS        0.0605      30%     0           # more than 2 times longer than using "global"
Functions assigning a global        0.0458      23%     32          # fastest. 32bits allocated? probably passed by copy... odd
Functions with $counter by ref      0.0707      35%     0           # slow for functions
Functions with $counter static prop 0.0524      26%     0

备注:

  • “修改全局函数”最快,达到23%
  • “实例化,存储然后调用动态方法”最长,所以100%
  • 存储实例花费大量内存,并占总时间的21%
  • “由ref传递$ counter作为参数”几乎是“修改全局函数的”两倍。
  • 调用一个修改静态属性的函数非常快,几乎是调用静态方法的一半。好笑
  • MyClass :: call()花费Singleton :: getInstance()-> call()的时间的75%,但花费了$ mySingleton-> call()的133%
  • MyClass :: call()的费用与(新MyClass)-> call()的费用一样
  • “静态”的成本等同于“动态未存储的动态”。真的很有趣!

开发人员实践的结论(于2020年1月生效):

  • 从不使用$ GLOBALS,'global $ myVar'超级快(并分配32位?)
  • 仅使用全局变量和函数进行编程是否可能是最快的PHP?守旧派摇滚!
  • 为许多方法调用存储实例,然后删除它是最佳选择。
  • 避免存储很多实例。
  • “实例化呼叫”和“静态呼叫”的费用相同

欢呼

PS:由于结果限制,即使结果不是100%稳定,我也无法进行更多运行(在整个工作台刷新后,我看到20%的变化) PS 2:如果要禁用3v4l.org的缓存,只需在代码中的任意位置添加一个空格