Facebook HHVM 團隊封閉開發三週的成果展

followflows發表於2014-01-29

【補充資訊】HipHop for PHP是一系列PHP指令碼語言的程式碼轉換器的集合,它包含HPHPc、HPHPi、HPHPd以及HHVM,這四個指令碼引擎各有所不同,但是他們共用相同的執行時期(Runtime)及工具集(Toolset)。HipHop是由Facebook所建立,他們用它來節省伺服器的資源。HipHop 由 C++ 和 C 語言所編寫,釋出時程式碼量已高達60萬行,它以自由軟體釋出,採用PHP許可證3.01版。(摘自維基百科

2013年11月4日開始,HHVM團隊進行了為期三週的“效能與相容性封閉開發”。此次封閉開發於11月22日正式結束。總體來看,封閉開發獲得了成功。衡量成功的三要素如下:

  • 1. 對21款開源框架做測試後,我們是否達到了平均單測通過率為99%的目標。
  • 2. 我們是否獲得了15%的效能提升收益。
  • 3. 團隊成員是否能堅持三週不刮鬍子。

hhvm team 1

HHVM團隊在封閉開發結束後的聚會上

相容性

封閉開發伊始,團隊認識到,僅僅擁有優異的效能還不足以使HHVM成為可靠的、可供大範圍使用的PHP執行環境。它必須能執行實際的、現成的PHP程式碼。所以,我們將這一點視為頭號工作任務(它將持續進行至2014年)。首先,我們在Github上通過“星標”數來尋找那些正被大多數人使用的熱門PHP專案,並確保這些專案的單元測試可順利執行於HHVM之上。

相容性成果

先來看一些數字。下圖是超過125次檔案修改之後,取得的相容性方面的部分成果。

Parity Results

封閉開發後的單元測試相容性成果

框架

封閉開發前 %

封閉開發後 %

Delta %

均值

89.96

99.58

9.62

assetic

77.94

100

22.06

codeigniter

88.24

100

11.76

composer

98.79

98.89

0.10

doctrine2

92.4

99.95

7.55

drupal

98.61

100

1.39

facebookphpsdk

100

100

0

idiorm

100

100

0

joomla

94.09

97.92

3.83

laravel

99.23

100

0.77

magento2

97.66

98.74

1.08

mediawiki

98.91

99.98

1.07

paris

100

100

0

pear

Fatal

92.66

92.66

phpbb3

94.58

99.5

4.92

phpmyadmin

96.15

94.16

-1.99

phpunit

96.29

97.03

0.74

slim

100

100

0

symfony

86.53

96.67

10.14

twig

99.23

100

0.77

yii

78.08

99.11

21.03

zf2

92.4

95.49

3.09

正如圖表及delta列所示,我們在努力下,近乎完全的成功改進了單元測試的相容性。

  • 1. 團隊使可在HHVM上100%跑通單元測試的開源專案數量翻了一番(從4個到8個),並且有另外4個專案的通過率在99%以上。
  • 2. Assetic,Symfony,Yii和CodeIngiter四個專案的相容性提升了10%以上。
  • 3. 全部21款框架的單元測試通過率均在90%以上。

大部分檔案更改已包含在HHVM 2.3版本中,以下是一些對單元測試結果有顯著影響的關鍵改進:

  • 1. 不要使陣列成為Traversable介面的例項
  • 2. 國際化支援
  • 3. PDO::sqliteCreateFunction()方法實現
  • 4. 開始支援真實的php.ini檔案。

無論怎樣,我相信你對我們的成果還有一些好奇:

1. 為什麼phpMyAdmin的相容性下降了呢?  這並不是“由於我們改動程式碼造成單元測試失敗”這個維度上的下降。這實際上可能是我們的測試框架指令碼在最初未能正確的載入全部測試用例造成的。我們修復了這個問題。儘管如此,我們正在調查這個下降的根本原因,以防我們破壞了某些東西。

2. 為什麼在11月24日左右有一個垂直跌落。我們提交了一處修改,本想將測試框架推向完美,但卻在執行時遭遇段異常。這個錯誤很快被修復了。

測試框架

正如前文所述,用來提升單測相容性的21款開源專案是根據流行程度挑選出來的。不過,挑選還基於他們是否使用PHPUnit以及他們在我們的框架上執行的如何。舉例來說,這些專案的單元測試數量,Symfony和ZF2各有超過一萬個測試用例,我們需要一個能以較快方式執行所有專案單元測試用例的測試框架。因此,我們開發了一個可並行下載、安裝和執行所有單元測試的指令碼。這個指令碼仍然在完善中,但它已幫助我們在30分鐘到一個小時內執行五萬個以上的單元測試用例並且可連續執行很多個小時。這個指令碼位於:HHVM Github repository

可能你已經注意到,你所喜愛的開源專案並未出現在上面的名單中。這是由於以下幾個原因造成的:首先,我們不可能在3周時間內覆蓋所有的開源專案。其次,雖然諸如CakePHP這樣的開源專案很重要,我們也計劃將它們加入測試框架,但由於一些安裝和配置方面的的問題(例如,要求資料庫)使我們無法在短時間內完成這一工作。

最後,正如我們在封閉開發前發表的博文中所述,HHVM團隊建立了很多“便利貼”來指引專案。便利貼顯示兩項內容:與便利貼上所述任務相關的失敗測試用例數及已開發天數。所以,我們通常按從左上角到右下角的順序工作,以使我們取得最大回報。

假設與警告

指出與上述統計值相關的假設及警告是很有必要的。

1. 整體單元測試通過百分比(98.5%)是簡單的,未加權平均數(即,所有百分比相加除以21).因此,類似Paris這種只含有50個單元測試用例的專案和類似Symfony這種包含一萬單元測試用例的專案擁有相同的權重。如果我們加權 (其中 Symfony 和 Zf2 會得到比Pair和 Idiorm更多的權重)計算這些百分比,整體通過百分比會有極小的跌幅 (績效跌幅的原因是因為在所有開源資源專案的通過百分比方差小)

2. 某些在HHVM上執行失敗的測試用例,同樣無法在PHP 5.5.x環境中執行。我們稱其為“小丑”同時在我們的測試框架中忽略他們。

3

3. 某些單元測試會導致我們的測試框架指令碼出錯(例如,死鎖)。我們遮蔽了這些測試用例並把它們歸為失敗用例。

已提交的相關專案的Pull Requests

為了能成功執行所有開源專案的單元測試,我們對它們的程式碼做了多次修改。例如,一些修改是為了支援我們的並行測試框架。在其他一些情況下,單元測試用例中實際bug。令人驚喜的是,就在我們封閉期間,那些專案維護者就審查了程式碼,並在大多數情況下接受了我們的pull requests。以下是一些pull request的例項:

框架 & pull request連結

描述

Pear

Support different style error messages

Doctrine2

Support the HHVM requirement of implementing methods of interfaces

Joomla

Support the definition usort() on equal values

phpbb3

Support our parallel testing framework

Slim

Support a string check in hash_hmac

Twig

Better use of strings instead of large integers in certain parsing scenarios

PHPUnit

Support HHVM in PHP_BINARY checks

Symfony

Support HHVM as one of the possible PHP executables

與Travis整合

HHVM 2.3版本公告中提到了與Travis CI整合。現在,我們開始持續的通過開源專案的單元測試,一些開源專案已把HHVM加入它們的Travis CI構建(棒極了)。以下是把HHVM加入CI構建的開源框架:

感謝以上專案能如此之快的支援我們。同樣,我們對其他專案也提交了很多類似的優秀pull request

效能

效能團隊的封閉開發目標是提升15%,最終獲得了16%的提升。

4

封閉開發後的效能成果

這意味著其他php程式碼也會有很大的提升空間。效能方面的收穫來自於大量的小改進和少量的大改動。以下是一些重大的修改:

1. 為特殊的函式呼叫方式生成程式碼。HHVM已經為普通函式和方法呼叫生成優質的程式碼,所以一些不常見的呼叫方式已經出現在我們的效能配置資料中。兩個最大的改動點是 call_user_func()和static::方法呼叫已被直譯器處理。現在HHVM可為每種呼叫型別生成優化過的機器程式碼。

2. 優化HHVM二進位制的佈局。HHVM是一套龐大的程式:編譯後的HHVM時鐘C++程式碼略低於100MB。當最頻繁呼叫的程式碼佔用空間少而不是分散在地址空間中時,CPU快取才工作的更好。所以,我們把最常用函式集合在一起作為二進位制的一部分。為了提升頁表快取效能,我們使用一個巨大的頁來對映這個部分。

3. 使用直譯器檢測熱點函式。HHVM解釋最初的幾個請求,以免浪費時間和空間去編譯啟動程式碼。我們為直譯器加入了尋找熱點函式並將其編譯為轉換快取一部分的功能。就像最後一個優化,這一項優化針對動態生成的程式碼,改進了程式碼位置。

4. 升級了我們的正規表示式庫。新版PCRE加入了針對正規表示式的JIT編譯器,這為HHVM帶來了一個令人興奮的效能提升。

個人衛生

我確信你在想:”所有的這些收益和統計很很好,但是鬍子呢?! ? “沒錯,你還記得我們再封閉開發前的博文:”剃鬚即失敗”。我很高興的宣告,我們在封閉開發中同樣成功地維持一個最低限度的面部衛生。這裡有一些圖片來證明這一點。

hhvm team 2 hhvm team 3

HHVM團隊人手一把剃鬚刀,準備對面部做清理

我們達到目標了麼?

還記得我們在前文提到的成功三要素麼?

  • 1. 對21款開源框架做測試後,我們是否達到了平均單測通過率為99%的目標。
  • 2. 我們是否獲得了15%的效能提升收益。
  • 3. 團隊成員是否能堅持三週不刮鬍子。

答案是:

  • 1. 接近完成
  • 2. 完美完成
  • 3. 完成。

未來(2014)

效能改進將永遠是HHVM團隊關注的核心。相容性優先順序將為1A。我們非常關心開源和PHP社群。我們將在2014年竭盡全力讓HHVM在效能與相容性兩方面成為一流,讓越來越多得開源專案及框架的單元測試(被)通過。大規模的真實php程式碼測試。請繼續關注我們的進展和計劃。最後,祝大家新年快樂。

相關文章