「Facebook 開發的高性能PHP虛擬機 HHVM 比官方的 PHP解釋器 快超過9倍」的說法是否屬實?
PHP5.2時代,這樣的測評結果是有可能的,這是PHP5.3依賴,PHP核心團隊把性能改善拍排在很前面的原因。HHVM快是因為JIT,能在運行時先動態優化再編譯執行:1.
比如
// 定義兩個function
function foo() {}
function bar() {}
// 調用只用到foo(),沒用到bar()
foo()
JIT在編譯前會把代碼先優化成
少編譯代碼自然可以節省很多內存,定義代碼本身是要執行的,少編譯也可以減少執行時間。極端的狀況比如你引入了一個幾百個類的庫,但只用到20個,那麼JIT就不會編譯沒有用到的大部分類了。2.
function foo() {}
foo();
又比如,下面的偽碼 假設calc(55)的執行結果是100,那麼JIT在編譯前把上述代碼優化為
run 100000 times:
x = calc(50)
然後編譯,少十萬次函數調用,當然可以省下很多CPU cycle。3.
run 100000 times:
x = 100
又比如,下面的偽碼
if (os == 「Linux") {
x = ""linux"
} else if (os == "Windows") {
x = "windows"
} else {
x = "unknown
}
如果在windows上跑這段代碼,那麼JIT在編譯之前可以將代碼先優化為:
這樣就省下了條件判斷。4.又比如,下面的偽代碼
x = ""windows"
if (x == 123) {}
普通PHP運行時,編譯出來的代碼要包含對x進行類型檢測,比如果是字元串就要轉換類型到integer(假設如此),然後再進行比較,額外的類型檢測和轉換都是開銷。
但是JIT在編譯上述代碼之前,可以事先確定x的類型(int),編譯出來的代碼可以省去類型檢測和轉換的開銷。JIT能從你寫的代碼里理出精簡的多執行路徑,先優化再編譯,目標碼效率自然就高了;類型化是動態編譯的其中一個方面,HHVM快不只因為有了強類型,而是JIT各種優化的結果。---python JIT PyPy - Welcome to PyPyruby JIT Rubiniusnodejs本身就是V8 JIT https://developers.google.com/v8/ JIT橫向比較,我沒留意過。上面的例子技術細節上未必準確,只為了方便直觀解釋問題。---http://hhvm.com/ Rather than directly interpret or compile PHP code directly to C++, HHVM compiles Hack and PHP into an intermediate bytecode. This bytecode is then translated into x64 machine code dynamically at runtime by a just-in-time (JIT) compiler. This compilation process allows for all sorts of optimizations that cannot be made in a statically compiled binary, thus enabling higher performance of your Hack and PHP programs.
What does a just-in-time (JIT) compiler do?
---hhvm不是趨勢,只是PHP生態圈的可選工具,PHP7才是。兩者性能差距已經不大了。99.99999%的項目不是Facebook,它們的性能瓶頸不是PHP,而是資料庫,所以不是非得要JIT這一層。
既然你都知道int $1 = 1;就是int i=1;了,你覺得既然C語言比PHP快那麼多,為什麼HHVM就不行呢?類型的動態綁定改成了靜態綁定啊。
類型的動態綁定用的是爽,但是代價不小。代價1:類型檢查要在運行時進行。代價2:變數值的空間要可變,不同的類型需要的存儲空間是不同的。代價3:處理動態綁定一般要解釋器來做。解釋器比編譯器慢多少不用說了吧。所以咯,如果能夠去掉上面的幾個代價,提速和節約內存是當然的。
其實聊HHVM的根本原因還是對PHP的優化
- 大家對於這一類「動態語言」比較常見的優化是,在性能瓶頸的地方用其他語言(代表性的C/C++)來代替,比如Twitter就將大量的業務邏輯放到了Scala里,而Rails只負責前端頁面上的展現。
- 另外一種比較高級的方案是優化官方語言的實現,比如Zend,如果分析過PHP的代碼,就會發現它的C代碼除去空行注釋後居然還有80+萬行(PHP 5.2.1),而Zend引擎部分只有不到10萬行。
- 比第一個方法更進一步的是,將PHP代碼轉成C/C++,然後編譯成本地代碼;
- 上面的效果很顯著,但是缺點也很明顯,就是開銷很大!WORE,那就來試著做一個更好的實現虛擬機;
從HHVM的發展軌跡上看,很類似於:
HPHPc------&>HPHP(08年開始Facebook就開始使用的HipHop,包括HPHPc、HPHPi、HPHPd)-----&>HHVM(維基百科:HHVM是在HPHPc的基礎上構建,它會將PHP代碼轉換成高級別的位元組碼,在運行時即時JIT編譯器會將這些位元組碼翻譯成機器碼。)而HHVM快的原因,在各種新聞報道中都提到了bytecode+JIT這個關鍵技術,其實研究JIT的路子也走了很長。比如:2010 年 IBM 日本研究院基於他們的JVM代碼開發了P9,性能是官方PHP的2.5到9.5倍,論文Evaluation of a just-in-time compiler retrofitted for PHP;
2008 年有人用 LLVM 實驗過zend虛擬機,結果是慢了 21 倍——llvm.org 的頁面;而且JIT本身也是會耗時的,對於一些很簡單的程序,執行過程上優化不完全,沒準還比interpreter慢,比如JAVA和.NET最初版本的JIT在性能測試時很容易就被幹掉,所以並不存在絕對的事情,更多還是在細節問題的處理上(參考HHVM的發布軌跡),其中最關鍵的上面的兄弟已經說到了,就是類型的推斷已經從語言轉移到了程序員身上,HHVM編譯出來的代碼直接使用了原生類型,避免了interpreter對參數的判斷和box、unbox的問題,正是這一點明顯提升了性能,甚至做到了和C語言的執行效果不大。
目前HHVM還是存在一些問題,比如對第三方擴展支持較少(比如MongoDB、Redis,在底層還是要用PHP代碼實現)、內存泄露問題等等,但長遠來看,除非PHP被其他替代掉,否則算是一個趨勢。
爭論這個完全 沒有意義~ 這就好比爭論公雞和母雞誰更能下單 ~ 除非你有機會能進程億級這個量級 才能有機會接觸這個。。 如果真到那個時候 你已經超越碼農存在 也不會在知乎上。 SO要有時間還是關注下 前言技術 了解語言本身的基礎 ~~
hhvm的效率並沒有到9倍,差不多是 PHP7的 1.1-1.5倍左右,也就是比php快一點點。而且,面臨很多兼容性問題,得不償失。
沒有得到社區的支持,PHP7才是未來,hhvm只會曇花一現
去一家公司面試時問過hhvm當時沒了解過
推薦閱讀:
※Zend opcode是如何被執行的?是要編譯為機器碼再執行嗎?
※能在郵件中嵌入PHP嗎?
※如何反駁服務端程序員聲稱SELECT出來的數據直接丟給客戶端的代碼最好?
※xlsx格式規範,不知類似文件應該從哪找?
※樹莓派集群,若要達到與伺服器相同的性能,需要多少個樹莓派?