摘要:周四正式發(fā)布了編程語言,將靜態(tài)類型以及一些現(xiàn)代的語言特性引入了。這是對優(yōu)化之路上的新里程碑。但是語言層面的優(yōu)化限制太多,對而言還是不夠用。其次是優(yōu)化運行的步驟。在這方面進行調(diào)整,可以提升運行的性能。值得注意的是,給的影響很大。
Facebook周四正式發(fā)布了Hack編程語言,將靜態(tài)類型以及一些現(xiàn)代的語言特性引入了PHP。這是Facebook對PHP優(yōu)化之路上的新里程碑。
Facebook為何要優(yōu)化PHP這個問題可以從不同角度來回答。簡單直接的回答是,F(xiàn)acebook的規(guī)模太大了。PHP的性能問題限制了Facebook的發(fā)展。從另一個角度來回答,則是要回答既然PHP不夠用,為什么不干脆換掉?
把PHP換掉也有“整體換”和“局部換”的區(qū)別。最徹底的方案就是完全離開PHP,用別的語言重寫一套。但是對于Facebook而言這個代價太高了。如果切換的話,多年來在PHP的積累就完全作廢了。而且Facebook的業(yè)務(wù)邏輯非常復(fù)雜,據(jù)說PHP代碼有2千萬行…… 而且,F(xiàn)acebook員工眾多,切換到一種新的語言,學習成本也不低。
既然整體換不可行,那就局部換吧。例如給PHP寫C/C++擴展,可以提升性能。但是PHP擴展開發(fā)起來成本高,一般只適用于比較穩(wěn)定的庫,適用范圍很有限。另一個方案將性能瓶頸的地方用其他語言實現(xiàn),然后通過RPC(Remote Procedure Call,遠程過程調(diào)用)在PHP和其他語言之間通訊。Twitter就用了這條路線,大量組件使用Scala和Java編寫,通過RPC與展現(xiàn)層的Rails通訊。事實上,F(xiàn)acebook在這方面已經(jīng)做了不少工作,為了減少RPC調(diào)用的開銷,F(xiàn)acebook還專門開發(fā)了Thrift。然而,C++開發(fā)成本比PHP高很多,不適合用在需要快速修改的地方,而且大量RPC調(diào)用終究會影響性能。
整體換不現(xiàn)實,Thrift不夠用,那么Facebook優(yōu)化PHP就勢在必行了。
Facebook要如何優(yōu)化PHP優(yōu)化PHP,最先想到的是作性能分析,找出瓶頸,然后進行對應(yīng)的優(yōu)化。Facebook為此開發(fā)了XHProf工具。XHProf精確到函數(shù)層面,數(shù)據(jù)收集組件使用C開發(fā)(PHP擴展),報告組件用了PHP。支持PHP 5.2以上版本,對于定位性能瓶頸很有幫助。
但是PHP語言層面的優(yōu)化限制太多,對Facebook而言還是不夠用。所以Facebook需要對PHP語言的實現(xiàn)本身進行優(yōu)化。
首先可以考慮的方案是改善PHP的官方實現(xiàn)。PHP的官方解釋器運行PHP代碼的過程可以分為兩步:第一步,將PHP編譯為bytecode;第二步,運行bytecode。那么改善PHP的官方實現(xiàn)就可以從這兩個方面著手。
首先是優(yōu)化編譯PHP的步驟,這方面的工作已經(jīng)有ZendOptimizerPlus做了。它會在內(nèi)存中緩存編譯好的bytecode,這樣以后訪問代碼的時候就可以直接訪問緩存好了的bytecode,省去了從磁盤讀取再重新編譯的開銷。但是由于PHP語言的動態(tài)性,這個方法的效果一般,最好的情況下也只能提升20%的性能。
其次是優(yōu)化運行bytecode的步驟。上面提到的ZendOptimizerPlus主要是優(yōu)化編譯PHP,但是也附帶做了一些bytecode運行的優(yōu)化。PHP有三種方式來運行bytecode:CALL、SWITCH和GOTO,默認使用CALL,也就是函數(shù)調(diào)用。優(yōu)化函數(shù)調(diào)用,常用的方法就是內(nèi)聯(lián)(Inline function),也就是將函數(shù)展開,將函數(shù)體插入替換調(diào)用該函數(shù)的地方,這樣可以節(jié)省每次調(diào)用函數(shù)帶來的額外時間開支。但是這種做法其實是用“空間換時間”,如果內(nèi)聯(lián)過頭了,空間開銷會很大,得不償失。在這方面進行調(diào)整,可以提升運行bytecode的性能。
此外還可以將整個PHP解釋器用匯編重寫,以快聞名的LuaJIT就是這么干的。
然而,無論是內(nèi)聯(lián)優(yōu)化還是用匯編重寫,代價都很大,而且如果優(yōu)化官方實現(xiàn)的話,還要考慮PHP的向下兼容……
既然這個方案不太現(xiàn)實,那么不如把PHP搬到JVM上吧?JVM性能相當不錯。
把PHP搬到JVM的工作,有人已經(jīng)做過了。例如,IBM的P8(已死)和Quercus(半死不活)。Facebook也研究過這個方案,2012年的時候,還有Facebook遷移到JVM的傳聞。其實Facebook早已放棄這條路線。根據(jù)Facebook的研究,Quercus的性能和Zend+APC相比,差不了太多。這一方案效果不理想的原因可能是,JVM本身性能的優(yōu)化是針對Java做的,其他語言在JVM上實現(xiàn),不一定能用到這些優(yōu)化。動態(tài)語言尤為如此。因為Java本身是靜態(tài)類型的,所以很多優(yōu)化JVM就沒必要做,而在JVM上跑的動態(tài)語言需要這些優(yōu)化。
既然JVM是為Java優(yōu)化的,搬上去不合適,那不如針對PHP開發(fā)一個VM?這樣就可以作大量針對性地優(yōu)化了。然而開發(fā)VM可沒有那么容易,成本不小,所以Facebook最初的選擇是將PHP編譯成C/C++之類性能優(yōu)異的語言。也就是HHVM的前身——HPHPc。具體的做法是將PHP翻譯為C++,然后再編譯。
相比VM,這樣的實現(xiàn)比較簡單,而且能放手做優(yōu)化(因為是離線編譯,所以可以用時間換性能)。但是PHP的很多動態(tài)內(nèi)容編譯成C++比較麻煩,因此HPHPc禁掉了eval()之類的特性,即使這樣,還是帶來了一些問題,特別是由于需要將動態(tài)include的文件都編譯在一起,最終的部署文件體積太龐大了,都過G了。
和HPHPc類似的項目有Roadsend和phc,前者已經(jīng)不維護了,后者也是命運坎坷。
編譯到C++的效果不好,所以Facebook最終決定,還是寫一個VM吧。
HHVMFaceBook開發(fā)HHVM的陣容相當豪華,其中包括
Andrei Alexandrescu, 《C++ Coding Standards》的作者。
Drew Paroski,改進了.NET虛擬機的JIT。
Jason Evans,jemalloc的開發(fā)者(jemalloc將Firefox的內(nèi)存消耗降低了一半)。
Keith Adams,VMware核心架構(gòu)。
Sara Golemon,《Extending and Embedding PHP》作者,PHP內(nèi)核領(lǐng)域的專家。
值得注意的是,Keith Adams給HHVM的影響很大。HHVM使用了JIT技術(shù),一般的代碼通過解釋器執(zhí)行(因為JIT也是有開銷的),而常用的代碼則使用JIT優(yōu)化。通常而言,VM判斷是否需要進行JIT優(yōu)化是通過以下兩種策略的一種:method-at-a-time(如果函數(shù)的執(zhí)行超過了閾值,就進行JIT優(yōu)化)和tracing (如果循環(huán)的執(zhí)行超過了閾值,就進行JIT優(yōu)化)。但是HHVM使用的是一種獨特的策略,basic-block-at-a-time,這個策略和VMware的x86 hypervisor相似。使用這個策略與Facebook希望支持類型推導的閉包有關(guān)。
Hack上面提到了類型推導。事實上,F(xiàn)acebook推出了一個運行在HHVM上的PHP改良語言——Hack。Hack里加入了類型的支持:
加了類型之后,除了方便大型團隊協(xié)作,避免編程中出現(xiàn)的錯誤之外,還有一個重要的原因就是能夠讓HHVM更好地優(yōu)化性能。JIT優(yōu)化最主要的方面就是根據(jù)類型來生成特定的指令,這樣可以減少大量的指令和條件判斷。而對于PHP這樣的動態(tài)語言,要推斷清楚類型是非常困難的,所以Hack就直接讓程序員寫上了。
兼容性HHVM除了作為Hack的VM之外,還可以運行原生的PHP。兼容性測試表明,HHVM對PHP的兼容度已經(jīng)達到98.58%了。由于HHVM使用了獨特的JIT優(yōu)化策略,因此Facebook自行開發(fā)了tracelet輔助庫,這個庫只支持x86 64bit系統(tǒng),所以HHVM也只能在64位系統(tǒng)上使用——不過這個問題不大,現(xiàn)在的服務(wù)器硬件基本都支持64位了。需要考慮的是PHP擴展的問題。由于PHP語言包含非常之多的擴展,而Facebook的HHVM只實現(xiàn)了自家用到的擴展,所以可能有為HHVM重寫PHP擴展的需要。好在相比為官方PHP實現(xiàn)寫擴展,為HHVM寫擴展比較容易,對性能要求不高的擴展可以使用純PHP編寫,然后編譯到HHVM二進制文件中即可,詳見HHVM wiki。還有一個要小心的問題就是HHVM是常駐內(nèi)存的,所以如果某處PHP代碼有內(nèi)存泄露問題的話,可能拖慢整個HHVM服務(wù)的速度,甚至導致HHVM掛掉。
參考HHVM 項目主頁
Hack項目主頁
The Hiphop compiler for PHP
編撰 SegmentFault
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/20689.html
摘要:但在密集計算方面比等靜態(tài)編譯語言差幾十倍甚至上百倍。一使用棧內(nèi)存在引擎和擴展中,經(jīng)常要創(chuàng)建一個的變量,底層就是一個指針。代碼中創(chuàng)建的變量也進行了優(yōu)化,直接在棧內(nèi)存上預(yù)分配。應(yīng)用層與底層在錯誤拋出的方式全部統(tǒng)一為異常。 原文:http://rango.swoole.com/archives/440最近PHP官方終于發(fā)布了傳說中的PHP7,雖然只是alpha版。PHP7號稱是新一代的PHP...
摘要:最近公布了一則消息分別與和簽署價值億和億美元訂單,這使得我們不禁好奇,以如此龐大的規(guī)模,能否在之上運行。年,營收為億美元。將年的營收除以年的服務(wù)器總量,那么每服務(wù)器營收為萬美元。 Facebook 大約在 2004 年成立,隨著逐漸成為美國五大科技巨頭之一,他們的基礎(chǔ)架構(gòu)也由大學寢室里的一臺服務(wù)器發(fā)展成為遍布全球的七個定制數(shù)據(jù)中心。隨著 Facebook 預(yù)計用戶數(shù)將增長至 19.4 億,他...
摘要:部署一個應(yīng)用程序的過程絕對是一個噩夢般的經(jīng)歷。準備開始,我們創(chuàng)建一個一個中包含怎樣創(chuàng)建你想要的鏡像的指令。使用告知使用官方社區(qū)最新版本的可用鏡像。這個鏡像在的可用版本。 注:本文由 Mike Ebinum 編寫,原文地址 Creating a Docker Container to run PHP, NGINX and Hip Hop VM (HHVM) showImg(ht...
摘要:部署一個應(yīng)用程序的過程絕對是一個噩夢般的經(jīng)歷。準備開始,我們創(chuàng)建一個一個中包含怎樣創(chuàng)建你想要的鏡像的指令。使用告知使用官方社區(qū)最新版本的可用鏡像。這個鏡像在的可用版本。 注:本文由 Mike Ebinum 編寫,原文地址 Creating a Docker Container to run PHP, NGINX and Hip Hop VM (HHVM) showImg(ht...
摘要:審視現(xiàn)在現(xiàn)在,語言發(fā)展迅速,由來自全球的幾十名核心開發(fā)者提供支持,而且開發(fā)方式也發(fā)生了變化。這些改進得益于新競爭者的出現(xiàn),尤其是開發(fā)的和。簡稱是和的解釋器,使用即時編譯器提升應(yīng)用的性能,并減少內(nèi)存用量。對于程序員來說,現(xiàn)在是令人激動的時刻。 就目前PHP語言的發(fā)展可以說是蒸蒸日上的,這得益于命名空間、性狀、閉包和內(nèi)置的操作碼緩存等有用的特性,所以PHP正在變成一門現(xiàn)代化腳本語言,并且現(xiàn)...
閱讀 1608·2021-11-19 09:55
閱讀 2837·2021-09-06 15:02
閱讀 3624·2019-08-30 15:53
閱讀 1230·2019-08-29 16:36
閱讀 1300·2019-08-29 16:29
閱讀 2351·2019-08-29 15:21
閱讀 679·2019-08-29 13:45
閱讀 2731·2019-08-26 17:15