「Facebook 開發的高性能PHP虛擬機 HHVM 比官方的 PHP解釋器 快超過9倍」的說法是否屬實?


PHP5.2時代,這樣的測評結果是有可能的,這是PHP5.3依賴,PHP核心團隊把性能改善拍排在很前面的原因。

HHVM快是因為JIT,能在運行時先動態優化再編譯執行:

1.

比如

// 定義兩個function
function foo() {}
function bar() {}
// 調用只用到foo(),沒用到bar()
foo()

JIT在編譯前會把代碼先優化成

function foo() {}
foo();

少編譯代碼自然可以節省很多內存,定義代碼本身是要執行的,少編譯也可以減少執行時間。

極端的狀況比如你引入了一個幾百個類的庫,但只用到20個,那麼JIT就不會編譯沒有用到的大部分類了。

2.

又比如,下面的偽碼

run 100000 times:
x = calc(50)

假設calc(55)的執行結果是100,那麼JIT在編譯前把上述代碼優化為

run 100000 times:
x = 100

然後編譯,少十萬次函數調用,當然可以省下很多CPU cycle。

3.

又比如,下面的偽碼

if (os == 「Linux") {
x = ""linux"
} else if (os == "Windows") {
x = "windows"
} else {
x = "unknown
}

如果在windows上跑這段代碼,那麼JIT在編譯之前可以將代碼先優化為:

x = ""windows"

這樣就省下了條件判斷。

4.

又比如,下面的偽代碼

if (x == 123) {}

普通PHP運行時,編譯出來的代碼要包含對x進行類型檢測,比如果是字元串就要轉換類型到integer(假設如此),然後再進行比較,額外的類型檢測和轉換都是開銷。

但是JIT在編譯上述代碼之前,可以事先確定x的類型(int),編譯出來的代碼可以省去類型檢測和轉換的開銷。

JIT能從你寫的代碼里理出精簡的多執行路徑,先優化再編譯,目標碼效率自然就高了;類型化是動態編譯的其中一個方面,HHVM快不只因為有了強類型,而是JIT各種優化的結果。

---

python JIT PyPy - Welcome to PyPy

ruby JIT Rubinius

nodejs本身就是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格式規範,不知類似文件應該從哪找?
樹莓派集群,若要達到與伺服器相同的性能,需要多少個樹莓派?

TAG:Facebook | 程序員 | PHP | 編程 | HHVM |