簡體   English   中英

靜態方法比非靜態方法快嗎?

[英]Is static method faster than non-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

當您的方法周圍不需要對象時,您應該始終使用靜態,並在需要對象時使用動態。 在您提供的示例中,您不需要對象,因為該方法不與類中的任何屬性或字段交互。

這個應該是靜態的,因為它不需要一個對象:

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++;
    }
}

速度差異很小,但是您必須創建一個對象來運行動態方法,並且該對象保存在內存中,因此動態方法使用更多內存和更多時間。

簡短的回答,因為我不想咆哮太多:

再快一點也無所謂。 如果您需要一些性能非常重要的東西,那么您考慮將每個函數調用減少 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

過早的優化是萬惡之源。 構建易於維護的代碼,如果它變得緩慢,請查看配置文件,它很可能會告訴您數據庫的文件系統有問題,您整理了所有內容后,將有一些非常具體的 php 部分需要優化。 如果你有干凈、多變的代碼,你可以加快速度。

“過早的優化是萬惡之源”,唐納德·克努斯(Donald Knuth)在40 年前說過。 您知道,當您擁有英特爾發明的新型 4004微處理器時 那個鼓的擊打力與任何馬匹一樣猛烈,我看不出它與最初的問題有何關聯。 事實上,我可能很幸運,但我還沒有在該領域看到這種猖獗行為的證據。 唉,在我們都可以過夜之前,互聯網上的某個人必須是對的。

更多關於主題,我認為接受的答案是最務實的,對問題的第一個評論是正確的。 靜態代碼與實例化代碼是否更快主要取決於語言的實現方式,我認為這些響應中的任何一個都不能充分回答有關 PHP 的問題。 任何人都知道 PHP 並想權衡?

一般來說,是的。 靜態方法和屬性工作得更快(PHP 5.3 除外)。

您可以參考PHP 中靜態和非靜態方法的或多或少的詳細比較

如果您打算使您的方法靜態並添加一個參數來傳遞您的類對象,那實際上會更慢。 我對此進行了基准測試,這是一個相當大的損失。 通過各種靜態方法傳遞對象是一種性能損失。 最好讓它們在對象中保持動態。

我相當肯定動態方法的性能更快,因為調用是在同一個對象中進行的。 在對象中使用靜態方法時,每次調用都會有一個額外的跳躍,因為調用不是在對象內進行,而是在類中進行。

使用靜態方法確實減少了內存使用量。 如果您可以在類中包含您的方法,則沒有它們的對象將變得更輕。 但在我的測試中最重要的是可訪問性。 直接訪問方法是最快的,而訪問靜態類方法是一個額外的跳躍。 這實際上是處理與內存的問題。 十有八九,動態更快。

類似的問題在這里: 在 PHP 中使用靜態方法和屬性使用更少的內存嗎?

我剛剛改進了 Stanislav 鏈接的基准以使其生效:

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 作為參數傳遞”幾乎是“函數修改全局”的 2 倍
  • 調用修改靜態屬性的函數非常快,幾乎是調用靜態方法的一半。 有趣的
  • MyClass::call() 花費了 Singleton::getInstance()->call() 時間的 75% 但 $mySingleton->call() 花費了 133%
  • MyClass::call() 的成本與 (new MyClass)->call() 一樣多
  • “靜態”在成本上等同於“動態實例化非存儲”。 十分有趣!

關於開發實踐的結論(2020 年 1 月有效):

  • 永遠不要使用 $GLOBALS,'global $myVar' 非常快(並且分配 32 位?)
  • 僅使用全局變量和函數編程是最快的 PHP 嗎? 老派搖滾!
  • 為大量方法調用存儲一個實例然后刪除它是最佳的。
  • 避免存儲大量實例。
  • “調用實例化”和“靜態調用”具有相同的成本

干杯

PS:由於限制,即使結果不是 100% 穩定,我也無法進行更多的運行(我看到整個工作台的某些刷新有 20% 的變化) PS 2:如果您只想禁用 3v4l.org 的緩存在代碼中的任意位置添加一個空格

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM