【導讀】徐漢彬曾在阿里巴巴和騰訊從事4年多的技術研發工做,負責過日請求量過億的Web系統升級與重構,目前在小滿科技創業,從事SaaS服務技術建設。最近,PHP7和HHVM的性能之爭成爲了一個討論熱點,它們都在提高PHP執行性能方面取得了突破性的進展。這篇文章,參考了兩個社區的技術新進展,爲你們科普和介紹它們的性能之爭。 php
根據「TIOBE編程語言排行榜」(榜單雖然統計方式有侷限,可是仍然不失爲一個比較好的參考),2010年PHP最高曾經在世界編程語言中排名第三。可見,PHP語言在PC互聯網時代的Web領域可謂叱吒風雲,擎天一柱。 前端
在PHP程序員中,曾經流傳着一個段子:程序員
某女:你能讓這個論壇的人都吵起來,我就跟你吃飯。
PHP程序員:PHP是世界上最好的語言!
某論壇炸鍋了,各類吵架……
某女:服了你了,咱們走吧!
PHP程序員:今天不行,我必定要說服他們,PHP必須是最好的語言。
好了,咱們言歸正傳,語言自己無分好壞,只是在各自使用的場景中解決不一樣的問題。互聯網的時代車輪是很快的,隨着移動互聯網的到來,在短短四年多的時間裏,移動端技術發展橫掃全球。與此同時,各類語言羣雄並起,而昔日輝煌的PHP從原來的編程語言的榜單看,降低到第六位(2014年12月榜單)。因而,唱衰PHP的聲音此起彼伏。redis
可是,鳥哥(惠新宸,PHP語言開發者之一)在2014年的Qcon分享中有一個數據,全球排名前100萬的網站中,81.3%使用的Web服務端腳本語言是PHP,2013年同期是78.3%。也就是說,PHP的在Web服務方面並無減小,只是在移動互聯網浪潮中,增長了不少的其餘語言技術的應用,進而被稀釋了。編程
最近關於PHP7和HHVM的性能對比,成爲了一個熱點的爭議話題,你們都在討論和關注哪個纔是PHP性能提高的將來。數組
HHVM是一個開源的PHP虛擬機,使用JIT的編譯方式以及其餘技術,讓PHP代碼的執行性能大幅提高。據傳,能夠將當前版本的原生PHP代碼提高5-10倍的執行性能。緩存
HHVM起源於Facebook公司,Facebook早起的不少代碼是使用PHP來開發的,可是,隨着業務的快速發展,PHP執行效率成爲愈來愈明顯的問題。爲了優化執行效率,Facebook在2008年就開始使用HipHop,這是一種PHP執行引擎,最初是爲了將Fackbook的大量PHP代碼轉成 C++,以提升性能和節約資源。使用HipHop的PHP代碼在性能上有數倍的提高。後來,Facebook將HipHop平臺開源,逐漸發展爲如今的HHVM。安全
1. PHP爲何慢?性能優化
PHP的慢是相對於C/C++級別的語言來講,事實上,PHP語言最初的設計,就不是用來解決計算密集型的應用場景。咱們能夠這樣粗略理解爲,PHP爲了提高開發效率,而犧牲了執行效率。網絡
咱們知道PHP一個很大的特色,就是弱類型特性,也就是說,我能夠隨意定義一個變量,而後給它隨意賦值爲各類類型的數據。以一個int整型數字爲例子,在C語言中:
int num = 200;//一般是4字節
可是,若是是PHP定義了一個一樣的變量,實際對應的存儲結構則是:
這個結構體將會佔據遠比C變量多得多的內存,PHP中定義方式以下:
$a = 200;//這變量將實際佔用對比C變量不少倍的存儲空間。
其實對PHP來講,不管存儲什麼類型的數據,都是用上述「通殺」的結構體實現。爲了兼容PHP程序員的變量類型「亂入」,PHP作到了對開發者的友好,可是對執行引擎很殘酷。單個變量內存消耗可能還不明顯,一旦用到PHP的數組等,則複雜度指數上升(數組的實現是HashTable)。而後,Zend引擎執行時,將這些PHP代碼編譯爲opcode(PHP的中間字節碼,格式有點相似於彙編),由Zend引擎逐行解釋執行。
不管是字符串的鏈接操做,仍是數組的簡單修改等,幾乎都是「PHP程序員一句話,Zend引擎跑斷腿」的節奏。所以,一樣的操做,對比C來講,PHP消耗了更多的CPU和內存等系統資源。除此以外,還有內存自動回收、變量類型判斷等等,都會增長系統資源的消耗。
例如,我用純PHP實現的快速排序函數和原生sort函數,排序10000個整型數字,來作一個耗時對比,結果以下:
原生的sort耗時3.44 ms,而咱們本身實現的PHP函數sort則是68.79 ms。咱們發現,二者執行效率差距巨大。個人測試方式,是計算函數執行先後的時間間隔,而不是整個PHP腳本從啓動到結束的時間。PHP腳本啓動和關閉過程,自己有着一系列的初始化和清理工做,也會佔據很多的耗時。
一般狀況下,PHP執行效率的排行是:
在通常狀況下,咱們並不推薦用過PHP實現邏輯複雜計算類型的功能,尤爲是Web系統流量比較大的場景下。所以,PHP程序員應該對PHP的各類原生函數和各種拓展有一個比較普遍的瞭解,在具體的功能實現場景中,尋求更原生的解決方案(原生接口或者拓展),而不是本身寫一堆複雜的PHP代碼來實現這類型功能。
若是有足夠的PHP拓展開發實力,將這類型業務功能重寫爲一個PHP拓展,也會大幅提高代碼的執行效率。這是一個很是不錯的方式,也被普遍應用PHP優化中。可是,本身編寫的PHP業務拓展的缺點也很明顯:
實際上,在互聯網一線企業中,更常見的解決方案,並不是增長PHP拓展,而用C/C++獨立寫一個服務server,而後PHP經過socket和服務server通訊來完成業務處理,並不將PHP自己和業務耦合在一塊兒。
不過,Web服務大部分的性能瓶頸都在網絡傳輸和其餘服務server的耗時上(例如MySQL等),PHP執行的耗時在總體耗時的佔用比例很是小,因此從業務角度來講,影響可能並不明顯。
2. HHVM提高PHP執行性能的方式
HHVM提高PHP性能的途徑,採用的方式就是替代Zend引擎來生成和執行PHP的中間字節碼(HHVM生成本身格式的中間字節碼),執行時經過JIT(Just In Time,即時編譯是種軟件優化技術,指在運行時纔會去編譯字節碼爲機器碼)轉爲機器碼執行。Zend引擎默認作法,是先編譯爲opcode,而後再逐條執行,一般每條指令對應的是C語言級別的函數。若是咱們產生大量重複的opcode(純PHP寫的代碼和函數),對應的則是Zend屢次逐條執行這些C代碼。而JIT所作的則是更進一步,將大量重複執行的字節碼在運行的時候編譯爲機器碼,達到提升執行效率的目的。一般,觸發JIT的條件是代碼或者函數被屢次重複調用。
普通的PHP代碼,由於沒法固定變量的類型,須要額外添加判斷類型的邏輯代碼,這樣PHP代碼是不利於CPU執行和優化的。所以,HHVM一般須要用到Hack寫法(爲了兼容某種特性而額外添加的技巧性質的代碼)的PHP代碼來「配合」,就是爲了讓變量類型固定,方便虛擬機編譯執行。PHP追求以一種形式來容納一切類型,而Hack則能夠將被容納的一切標記上肯定的類型。
PHP代碼的Hack寫法的例子:
上面的例子中,PHP代碼主要被添加上了變量類型。Hack寫法的整體方向,就是將以前「動態」的寫法變爲「靜態」的寫法,來配合HHVM。
HHVM由於它的高性能而吸引了很多人的關注,一些一線互聯網公司也開始跟進使用。從純語言執行性能測試結果來看,HHVM領先了開發中的PHP7版本很多。
不過,從具體業務場景來看,HHVM和PHP7的差距並無那麼大,以WordPress開源博客首頁爲測試場景的結果中,他們目前的差距並不明顯。
可是,PHP7目前還在開發中,就已經可用的技術方案來看,目前的HHVM略勝一籌。不過,HHVM的部署和應用都存在一些的問題:
HHVM畢竟是一個相對比較新的開源項目,發展到成熟仍然須要必定時間。
PHP長期以來飽受批評的性能問題,將會在這個版本獲得大幅度的改善。版本中間沒有PHP6哈,聽說,是由於這個版本曾經立過項目,後來大部分功能都在5.x的版本里實現了,爲了不混淆,下一個大版本直接就是PHP7。(幾年之前,我還看到過關於PHP6的書籍。)
1. PHP7的介紹
雖然PHP7的正式版本可能要到2015年的10月份才發佈,不過明年6月份應能夠看見一個測試版本了,以後是3-4個月的質量保證。
PHP社區的項目計劃以下:
由於項目仍然處於開發中的緣由,從表格中,能夠看見的特性描述都比較模糊。確定有更多的其餘特性,只是還沒有公佈。下面的這些,是從PHP社區看見的,由於PHP7是一個開發中的項目,下面的這些也不必定準確,不過,不妨礙咱們一塊兒來看看。
上面的特性中,最使人期待的就是PHPng的性能優化,PHP社區已經放出了一些性能的測速數據。從數據上看,PHPng的執行性能比起項目啓動之初,已經有接近1倍的提高。這個成績已經很是不錯,何況,最關鍵的是PHP7的優化計劃還有不少還沒有完成。等到都所有完成了,相信咱們能夠看見一個性能更高的PHP7。
這測速數據是來自於PHP社區(wiki.php.net/phpng),截取了一部分的數據:
對其當前PHP5.6版本,PHPNG的10月份性能提高已經很是明顯了:
簡單翻譯下:
2. PHP的弱類型爭議
PHP被爭議的特色不少,可是隨着語言版本的發佈和完善,功能和特性方面的批評開始變少了。可是,PHP的「弱類型」特性,卻明顯受到更多的爭議,從HHVM經過Hack的方式直接「去掉」了「弱類型」特性能夠看出,HHVM並不喜歡「弱類型」特性。然而,在咱們不少PHP程序員的眼中,這倒是PHP的重要優勢之一。PHP裏的變量被設計得隨性和飄逸,海納百川,一切皆可包容,不是讓語言顯得更爲簡單嗎?
實際上,有些人認爲它是個嚴重的問題,對於「弱類型」的批評觀點大體以下:
他們認爲,這些都不符合「所見即所得」的簡單性,而語法嚴謹的語言更高效率,也更容易「理解」。
受到相似批評的還有Javascript等語言,由於它在這個問題上的表現是同樣的。可是,一門語言最終被大規模使用,必然有它們的道理。PHP成爲Web服務開發的首選腳本語言,Javascript則直接稱霸Web前端領域,能走到這一步都不多是偶然因素,開發者們用腳投票選擇了它們。編程語言是人類和機器溝通的橋樑,終極追求是實現「人人皆可編程」的宏偉目標。
縱觀語言發展歷史,從0和1的機器碼開始,到彙編語言,而後到C語言,再到動態腳本語言PHP。執行效率呈指數降低,可是,學習門檻也呈指數下降。PHP語言不只屏蔽了C的內存管理和指針的複雜性,並且更進一步屏蔽了變量類型的複雜性。提高了項目開發的效率,下降了學習的門檻,但同時犧牲了必定的執行性能。而後,HHVM的Hack給咱們一種「迴歸原始」的感受,從新引入了變量的複雜性。固然,不一樣的語言解決不一樣場景下的問題,並不可以一律而論。
HHVM對PHP的性能提高,讓人眼前一亮,而磨刀霍霍的PHP7則讓人萬分期待。二者都是極其優秀的開源項目,都在不斷前進和發展中。就目前而言,由於距離PHP7正式版的發佈還有比較長的一段時間,因此當前性能優化方案的首選固然是HHVM。不過,就我我的而言,我比較看好PHP7,由於它更能作到PHP代碼的向下兼容。若是二者性能相差不大,我會選擇簡單的那個。
參考資料:
更多《問底》內容