1. 程式人生 > 其它 >php反轉數字_4 個常見的 PHP 程式碼效能對比

php反轉數字_4 個常見的 PHP 程式碼效能對比

技術標籤:php反轉數字

通常我會使用常規的、顯而易見的 PHP 函式來編寫程式碼來解決相應的問題。但對於其中一些問題,我遇到了特別提高效能的替代解決方案。

在本文中,我想介紹其中的一些替代方案。如果你正在尋找在生產中進一步減少執行時間的可能性,這將非常有用。讓我們來看看哪些 PHP 方法可能會被效能更好的方法取代,以及是否有任何成本或權衡。

所有這些方法都在本地 Web 伺服器上使用 PHP 7.4 進行了測試
歡迎加入 我的官方群

1. 刪除重複項

你有一個包含重複項的大型陣列,並且希望刪除它們,以便只有一個具有唯一值的陣列。

常規

array_unique($array);

其他方式

array_keys(array_flip($array));

效能

我建立了一個 400 萬的陣列,其中有 300 萬個重複項,這是最好的優化結果:

bd7081c4bbf94e79358087de569db3ea.png

其他方式比常規方式 快了 1.8倍 (44.87%) . 平均也有大約 1.5 倍 (30%) 的提升。總結:這僅適用於一維陣列,因為array_flip會反轉鍵和值.

2. 獲取隨機的陣列元素

你想從一個大陣列中獲取一個隨機值

常規

array_rand($array);

其他方式

$array[mt_rand(0, count($array) - 1)];

效能

我建立了一個包含 500 萬個元素的陣列,這是最佳結果:

2e464056e450b0c173340e3a55587f9e.png

替代方法在此測量中快27.3 倍(96.33%)。平均快 8 倍 (87%)。這個結果特別令人驚訝,因為mt_rand是 MersenneTwister 隨機數生成器的實現,而且從 PHP7.1 開始,內部隨機化演算法已更改為使用完全相同的演算法。

3. 字母數字字元測試

如果你有一個字串,並且希望測試它是否只包含字母數字字元。

常規

preg_match('/[a-zA-Z0-9]+/', $string);

其他方式

ctype_alnum($string);

效能

我建立了一個包含超過 100k 字母數字和非字母數字字串的陣列。以下是排名靠前的結果:

6fcbf80cf844e312ed4b004ae86314d4.png

替代方法在此測量中快 7.5 倍 (86.59%)。 平均而言,它快了約 4 倍 (76%)。

同樣的道理也可以應用於 ctype_alpha() 命令 (檢查字母字元) 和 ctype_digit() 命令 (檢查數字字元)。

4. 替換子字串

你有一個字串,並且希望用另一個子字串替換它的一部分。

常規

str_replace('a', 'b', $string);

其他方式

strtr($string, 'a', 'b');

效能

我建立了一個包含 500 萬個隨機字串的陣列。以下是排名靠前的結果:

fabc2e15ffaaa967e454598b31f4be5d.png

替代方法在此測量中快2.2 倍(54.83%)。平均快 2 倍 (51%)。

額外的效能改進

以下是我在編碼約定中搜集的一些附加方法,我發現它們可以略微提高效能 (如果適用):

  • 更喜歡 JSON 而不是 XML
  • 在之前宣告變數,而不是在迴圈的每次迭代中宣告變數
  • 避免迴圈頭部中的函式呼叫 (在每次迭代中呼叫的 for ($i=0; $i<count($array); $i) 中的 count() 中)
  • 登出消耗記憶體變數
  • 首選 select 語句而不是多個 if 語句
  • 優先選擇 require/include 而不是 require_once/include_once (確保正確的操作碼快取)

最後一句話:我知道關於過早優化的討論。我同意,生產中的效能取決於諸如資料庫查詢之類的瓶頸,在處理效能時應該重點關注這些瓶頸。但我認為,如果有更快的替代方案,例如,在 regex 更容易處理和維護的情況下,為什麼不使用它們呢?

總結

我們已經看到,即使使用當前的 PHP 7.4 (已經比以前的 PHP 版本快得多),也有可能使用其他方法進一步提高指令碼效能。如果你希望自己驗證本文中提供的數字,我建立了一個包含所有測試的儲存庫:

GitHub Repofaster-php

測試提高 PHP 指令碼效能的不同方法

我用 Bart van Hoekelen 的偉大工具來衡量執行時間。

如果你知道提高某些 PHP 函式效能的方法,請不要猶豫在這裡發表評論或在上面的 repo 中建立 issue/PR 。