亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么用 min() 和 max() 比較數字比條件語句慢

為什么用 min() 和 max() 比較數字比條件語句慢

PHP
qq_遁去的一_1 2021-11-05 15:17:23
我不得不優化運行緩慢的大型數據集的代碼,這些代碼看起來不錯。在測試和記錄執行時間后,我發現循環中幾乎沒有兩個整數的 max() 比較。然后在快速瀏覽文檔后,我看到了以下評論:“我有幾次使用 max 比使用 if/then/else 構造要慢得多。一定要在你的例程中檢查這個!”所以我用三元運算符替換它,執行時間快了大約 2/3。然后我開始好奇為什么 max() 的工作速度比一個簡單的語句慢得多,以及這個函數的背后是什么。但到目前為止我找不到任何解釋。同樣在過去,我在 array_search() 中遇到了類似的問題,它的工作速度比 foreach with 語句慢得多。我在 PHP 7.1 上運行了測試。$firstLoop = microtime(true);for ($i = 0; $i < 1000000; $i++) {    $testOne = max($i, 1000000);}error_log(microtime(true) - $firstLoop); $secondLoop = microtime(true); // 1.3123650550842for ($i = 0; $i < 1000000; $i++) {    $testTwo = $i > 1000000 ? $i : 1000000; }error_log(microtime(true) - $secondLoop); // 0.090374946594238
查看完整描述

3 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

max是一個完整的函數調用并允許任意參數列表。與可以在不設置完整函數調用上下文的情況下內聯執行的簡單比較相比,這有很多開銷。在您的示例中,您正在執行一百萬次函數調用,這總共加起來。


兩種不同的方法(支持(并且可以做)不同的事情)沒有必要以相同的方式實現,即使它們給出與您的示例相同的結果。


您可以從 VM 生成的操作碼中看到這一點,第一次調用生成以下語句:


   6     6    >   INIT_FCALL                                               'max'

         7        SEND_VAR                                                 !1

         8        SEND_VAL                                                 1000000

         9        DO_ICALL                                         $8      

        10        ASSIGN                                                   !2, $8

   5    11        POST_INC                                         ~10     !1

        12        FREE                                                     ~10

        13    >   IS_SMALLER                                       ~11     !1, 1000000

而第二種情況只生成 JMP 調用:


        27      > JMP                                                      ->36

  14    28    >   IS_SMALLER                                       ~18     1000000, !1

        29      > JMPZ                                                     ~18, ->32

        30    >   QM_ASSIGN                                        ~19     !1

        31      > JMP                                                      ->33

        32    >   QM_ASSIGN                                        ~19     1000000

        33    >   ASSIGN                                                   !4, ~19

  13    34        POST_INC                                         ~21     !1

        35        FREE                                                     ~21

        36    >   IS_SMALLER                                       ~22     !1, 1000000

JMP call 不必設置整個函數調用結構,因此可以更快地執行。


這也是一文不值的是,在一般的差異似乎是大約1/2的時間用于對PHP的當前版本的簡單對比。


查看完整回答
反對 回復 2021-11-05
?
交互式愛情

TA貢獻1712條經驗 獲得超3個贊

在以前的 PHP 版本中,它比這慢得多。他們正在提高每個庫函數的速度,如新版本中的 max() 和 min() 函數。

正如 MatsLindh 在 max() 和 min() 等庫函數中所說的那樣,它們有很多開銷,我們在第二部分中所做的簡單比較中不需要這些開銷。

如果您閱讀PHP 手冊 max()它說...

如果第一個也是唯一的參數是數組,則 max() 返回該數組中的最大值。如果至少提供了兩個參數,則 max() 返回這些值中的最大值。

所以它首先檢查它是否是一個數組,這需要一些執行時間。在您的情況下,您只是在比較值而不是檢查數組。

將使用標準比較規則比較不同類型的值。例如,一個非數字字符串將與一個整數進行比較,就好像它是 0 一樣,但多個非數字字符串值將按字母數字進行比較。返回的實際值將是未應用轉換的原始類型。

所以在 max 函數中有更多的函數需要一些時間來執行。

除此之外,該功能比簡單的比較需要更多的時間。這就是為什么像 Lisp 這樣基于函數的編程語言比一個像樣的哈希表慢的原因。

他們需要的基礎設施不可避免地增加了理論上使用手工匯編程序可以實現的開銷。特別是,一流的詞法閉包只適用于垃圾收集,因為它們允許值超出范圍。

可能是當今函數式語言的最大瓶頸:過度的分配率。


查看完整回答
反對 回復 2021-11-05
?
天涯盡頭無女友

TA貢獻1831條經驗 獲得超9個贊

確保您使用多次,然后將它們平均,然后決定哪些代碼運行得更快。在我的機器上,使用 max 函數的代碼平均(10 個結果)為0.08,if 語句為0.044 我們可以看到 if 條件花費的時間幾乎是 min 函數的一半。如果我們考慮調用函數時會發生什么,那么這個時間差是有意義的。

1) 函數的參數存儲在堆棧中。按平臺特定順序。

2)返回值的位置在堆棧上“分配”

3) 函數的返回地址也存儲在堆棧或專用 CPU 寄存器中。

4) 函數(或者實際上是函數的地址)被調用,要么通過 CPU 特定的調用指令,要么通過普通的 jmp 或 br 指令(跳轉/分支)

5) 函數從堆棧中讀取參數(如果有)并運行函數代碼

6) 函數返回值存放在指定位置(堆棧或CPU專用寄存器)

7) 執行跳回到調用者處并清空堆棧(通過將堆棧指針恢復到其初始值)。

訪問調用方法/函數時匯編語言中會發生什么?

如果我們考慮到所有這些細節以及函數內部增加的代碼行來處理多個條件來搜索最大值,那么時間差是有道理的。

訪問https://www.php.net/manual/en/function.max.php查看函數處理的增加代碼行數從而增加執行時間的條件。對 array_search 和 min 函數的類似響應。


查看完整回答
反對 回復 2021-11-05
  • 3 回答
  • 0 關注
  • 368 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號