LNMP 性能優化之 PHP 性能優化

PHP 做一門弱類型動態語言,在上手容易和開發快速同時,也會導致一些新手寫出不規範的代碼。比如在遞歸當中連接數據庫讀取數據;一次性從文件中讀取大量的數據,處理完後卻不主動釋放內存;在遍歷和循環中重複計算某個變量等等;數組的鍵沒有加引號導致先查找常量集,都會導致 PHP 程序性能下降。

PHP 作為一門 Web 後端腳本語言,好處是能夠快速實現 Web Application 所需功能,而且容易部署。缺點就是相對於強類型靜態語言如 Java/C/C++ 來說,PHP 的性能較差,在實現計算密集型的業務時沒有任何優勢。同時也由於 PHP 是同步阻塞的 IO 模型,在高併發請求的場景下容易遇到瓶頸,需要通過 PHP 相關擴展來解決相關技術難題。

PHP 作為一門膠水語言,勢必會連接各種各樣服務。常見的服務如:MySQL、Redis、MongoDB 等數據庫,C/C++、GO、Java 等語言編寫的後端服務。倘若 PHP 所連接服務不穩定,勢必也會對 PHP 造成一定的性能影響。

在某些情況,某個 PHP 程序或某段 PHP 代碼莫名其妙地出現相當耗時的情況,不知道是 PHP 本身出現了問題,還是所用的框架出現了問題,亦或是 PHP 周邊甚至是硬件的問題。這個時候就需要通過工具進行排查。常用的工具有:PHP-Xhprof、PHP-XDebug。

PHP 的底層是由 C 語言組成的。每次運行 PHP 的程序,都是需要經過 C 語言遍寫的 Zend 引擎來解析 PHP 文件,將其編譯成為 Opcodes 後再去執行。就這樣一來一回就消耗了不少時間和硬件性能。

PHP 運行流程

Scanning(Lexing),將 PHP 代碼轉換為語言片段(Tokens)。


Parsing,將 Tokens 轉換成簡單而有意義的表達式(Expression)。

Compilation,將表達式編譯成 Opocdes。

Execution,順次執行 Opcodes,每次一條,從而實現 PHP 腳本的功能。

(*.php) -> scanner -> (Tokens) -> Parser -> (Expression) -> Compilation -> (Opcodes) -> Execution -> (Output)

PHP 語言級性能優化

儘可能地使用內置函數來完成任務

能使用 PHP 內置方法解決的問題,就不要自己手寫代碼,一是手寫代碼一般冗餘較多,可讀性不佳。二是手寫代碼需要解析編譯為底層代碼再執行,沒有 PHP 內置函數的性能高。

for & range() 實現同一功能

for ($i = 0; $i <1000; $i++) {

$array1[$i] = $i+1000;

}

range(1000,1999);

以 foreach、in_array 和 array_merge 實現同一功能對比說明:

LNMP 性能優化之 PHP 性能優化

以 foreach 和 array_column() 實現同一功能對比說明:

LNMP 性能優化之 PHP 性能優化

以 foreach 和 array_filter() 實現同一功能對比說明:

LNMP 性能優化之 PHP 性能優化

從服務器方面進行優化,可以選擇將服務器不安裝其他後端服務軟件,僅僅安裝 PHP 以及其必要擴展。使單機的性能全部向 PHP 傾斜。同時也對 PHP 的相關參數進行優化,將 PHP 單機服務器性能最大化。在大數據、高併發的場景下,可以嘗試將 PHP 服務器集群化,通過負載均衡,將網絡請求分配至不同的 PHP 單機服務器處理。


分享到:


相關文章: