從原理分析PHP性能

從原理分析PHP的性能,主要從以下幾個(gè)方面:內(nèi)存管理、變量、函數(shù)、運(yùn)行機(jī)制、網(wǎng)絡(luò)模型來(lái)進(jìn)行分析。

1.內(nèi)存管理

類似Nginx的內(nèi)存管理方式,PHP在內(nèi)部也是基于內(nèi)存池,并且引入內(nèi)存池的生命周期概念。在內(nèi)存池方面,PHP對(duì)PHP腳本和擴(kuò)展的所有內(nèi)存相關(guān)操作都進(jìn)行了托管。對(duì)大內(nèi)存和小內(nèi)存的管理采用了不同的實(shí)現(xiàn)方式和優(yōu)化。在內(nèi)存分配和回收的生命周期內(nèi),PHP采用一次初始化申請(qǐng)+動(dòng)態(tài)擴(kuò)容+內(nèi)存標(biāo)識(shí)回收機(jī)制,并且在每次請(qǐng)求結(jié)束后直接對(duì)內(nèi)存池進(jìn)行重新mask。

2.變量

總所周知,PHP是一種弱變量類型的語(yǔ)言,所以在PHP內(nèi)部,所有的PHP變量都對(duì)應(yīng)成一種類型Zval,其中具體定義如下:

在變量方面,PHP做了大量的優(yōu)化工作,比如說(shuō)Reference counting和copy on writer機(jī)制。這樣能夠保證內(nèi)存使用上的優(yōu)化,并且減少內(nèi)存拷貝次數(shù)(請(qǐng)參考http://blog.xiuwz.com/2011/11...)。在數(shù)組方面,PHP內(nèi)部采用高效的hashtable來(lái)實(shí)現(xiàn)。

3.函數(shù)

在PHP內(nèi)部,所有的PHP函數(shù)都回轉(zhuǎn)化成內(nèi)部的一個(gè)函數(shù)指針。比如說(shuō)擴(kuò)展中函數(shù)
ZEND_FUNCTION ( my_function );//類似function my_function(){}
在內(nèi)部展開后就會(huì)是一個(gè)函數(shù)
void zif_my_function ( INTERNAL_FUNCTION_PARAMETERS );
void zif_my_function(
int ht,
zval * return_value,
zval * this_ptr,
int return_value_used,
zend_executor_globals * executor_globals
);
從這個(gè)角度來(lái)看,PHP函數(shù)在內(nèi)部也是對(duì)應(yīng)一個(gè)函數(shù)指針。

4.運(yùn)行機(jī)制

在話說(shuō)PHP性能的時(shí)候,很多人都會(huì)說(shuō)“C/C++是編譯型,JAVA是半編譯型,PHP是解釋型”。也就是說(shuō)PHP是先動(dòng)態(tài)解析再代碼運(yùn)行的,所以從這個(gè)角度來(lái)看,PHP性能必然很差。

的確,從PHP腳本運(yùn)行來(lái)輸出,的確是一個(gè)動(dòng)態(tài)解析再代碼運(yùn)行的過(guò)程。

PHP的運(yùn)行階段也分成三個(gè)階段:
●Parse。語(yǔ)法分析階段。
● Compile。編譯產(chǎn)出opcode中間碼。
● Execute。運(yùn)行,動(dòng)態(tài)運(yùn)行進(jìn)行輸出。

5.動(dòng)態(tài)運(yùn)行

從上面的幾個(gè)分析來(lái)看,PHP在內(nèi)存管理、變量、函數(shù)、運(yùn)行機(jī)制等幾個(gè)方面都做了大量的工作,所以從原理來(lái)看,PHP不應(yīng)該存在性能問(wèn)題,性能至少也應(yīng)該和JAVA比較接近。

但為什么還有很多人感覺PHP慢呢?尤其是一些計(jì)算量的性能對(duì)比上,總發(fā)現(xiàn)PHP處理的性能相對(duì)比較低效。這個(gè)時(shí)候就不得不談PHP動(dòng)態(tài)語(yǔ)言的特性所帶來(lái)的性能問(wèn)題了,由于PHP是動(dòng)態(tài)運(yùn)行時(shí),所以所有的變量、函數(shù)、對(duì)象調(diào)用、作用域?qū)崿F(xiàn)等等都是在執(zhí)行階段中才確定的。這個(gè)從根本上決定了PHP性能中很難改變的一些東西:在C/C++等能夠在靜態(tài)編譯階段確定的變量、函數(shù),在PHP中需要在動(dòng)態(tài)運(yùn)行中確定,也就決定了PHP中間碼不能直接運(yùn)行而需要運(yùn)行在Zend Engine上。

6.網(wǎng)絡(luò)模型

目前采用PHP的方式,比較理想和通用的模式是采用fastcgi(PHP-FPM)。Php-fpm在網(wǎng)絡(luò)模型上比較類似nginx,采用了多進(jìn)程Master+多worker的模式。Php-fpm本身是基于libevent中的epoll模型。從網(wǎng)絡(luò)模型來(lái)看,該方式也不會(huì)和其他網(wǎng)絡(luò)模型存在性能差異。

7.結(jié)論

從上面分析來(lái)看,在基礎(chǔ)的內(nèi)存管理、變量、函數(shù)、運(yùn)行機(jī)制、網(wǎng)絡(luò)模型方面,PHP本身并不會(huì)存在明顯的性能差異,但由于PHP的動(dòng)態(tài)運(yùn)行特性,決定了PHP和其他的編譯型語(yǔ)言相比,所有的變量查找、函數(shù)運(yùn)行等等都會(huì)多一些hash查找的CPU開銷和額外的內(nèi)存開銷,至于這種開銷具體有多大,可以通過(guò)后續(xù)的基準(zhǔn)性能和對(duì)比分析得出。

因此,也可以大體看出PHP不太適合的一些場(chǎng)景:大量計(jì)算性任務(wù)、大數(shù)據(jù)量的運(yùn)算、內(nèi)存要求很嚴(yán)格的應(yīng)用場(chǎng)景。如果要實(shí)現(xiàn)這些功能,也建議通過(guò)擴(kuò)展的方式實(shí)現(xiàn),然后再提供鉤子函數(shù)給PHP調(diào)用。這樣可以減低內(nèi)部計(jì)算的變量、函數(shù)等系列開銷。

點(diǎn)關(guān)注,不迷路

好了各位,以上就是這篇文章的全部?jī)?nèi)容了,能看到這里的人呀,都是人才。之前說(shuō)過(guò),PHP方面的技術(shù)點(diǎn)很多,也是因?yàn)樘嗔?,?shí)在是寫不過(guò)來(lái),寫過(guò)來(lái)了大家也不會(huì)看的太多,所以我這里把它整理成了PDF和文檔,如果有需要的可以點(diǎn)這里https://shimo.im/docs/rjJttdvCJpYtHpW3/ 《進(jìn)階PHP月薪30k>>>架構(gòu)師成長(zhǎng)路線【視頻、面試文檔免費(fèi)獲取】》

24020938-0e1d4138a0a22218.png

24020938-7cffd24782dd56f9.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • PHP7號(hào)稱是新一代的PHP,官方開發(fā)組對(duì)Zend引擎底層做了大量修改來(lái)優(yōu)化PHP的性能??梢哉f(shuō)PHP7這個(gè)版本的...
    it阿布閱讀 719評(píng)論 0 4
  • PHP 是一門托管型語(yǔ)言,在 PHP 編程中,程序員不需要手工處理內(nèi)存資源的分配與釋放(使用 C 編寫 PHP 或...
    張清柏閱讀 1,098評(píng)論 0 1
  • 本文是php-internals的讀書筆記. 概述1) 操作系統(tǒng)直接管理著內(nèi)存,所以操作系統(tǒng)也需要進(jìn)行內(nèi)存管理,計(jì)...
    codefine閱讀 10,193評(píng)論 3 29
  • 關(guān)于前端性能優(yōu)化問(wèn)題詳解 出處:http://segmentfault.com/blogs 前端性能優(yōu)化指南 AJ...
    bennnnn閱讀 1,721評(píng)論 2 4
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月,有人笑有人哭,有人歡樂有人憂愁,有人驚喜有人失落,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,889評(píng)論 28 54

友情鏈接更多精彩內(nèi)容