本人翻译的一篇文章,首发于伯乐在线

【补充信息】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团队在封闭开发结束后的聚会上

兼容性

封闭开发伊始,团队认识到,仅仅拥有优异的性能还不足以使HHVM成为可靠的、可供大范围使用的PHP运行环境。它必须能运行实际的、现成的PHP代码。所以,我们将这一点视为头号工作任务(它将持续进行至2014年)。首先,我们在GitHub上通过“星标”数来寻找那些正被大多数人使用的热门PHP项目,并确保这些项目的单元测试可顺利运行于HHVM之上。

兼容性成果

先来看一些数字。下图是超过125次文件修改之后,取得的兼容性方面的部分成果。

封闭开发后的单元测试兼容性成果

框架

封闭开发前 %

封闭开发后 %

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. 某些单元测试会导致我们的测试框架脚本出错(例如,死锁)。我们屏蔽了这些测试用例并把它们归为失败用例。

已提交的相关项目的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%的提升。

封闭开发后的性能成果

这意味着其他php代码也会有很大的提升空间。性能方面的收获来自于大量的小改进和少量的大改动。以下是一些重大的修改:

1. 为特殊的函数调用方式生成代码。HHVM已经为普通函数和方法调用生成优质的代码,所以一些不常见的调用方式已经出现在我们的性能配置数据中。两个最大的改动点是 call_user_func()和static::方法调用已被解释器处理。现在HHVM可为每种调用类型生成优化过的机器代码。

2. 优化HHVM二进制的布局。HHVM是一套庞大的程序:编译后的HHVM时钟C++代码略低于100MB。当最频繁调用的代码占用空间少而不是分散在地址空间中时,CPU缓存才工作的更好。所以,我们把最常用函数集合在一起作为二进制的一部分。为了提升页表缓存性能,我们使用一个巨大的页来映射这个部分。

3. 使用解释器检测热点函数。HHVM解释最初的几个请求,以免浪费时间和空间去编译启动代码。我们为解释器加入了寻找热点函数并将其编译为转换缓存一部分的功能。就像最后一个优化,这一项优化针对动态生成的代码,改进了代码位置。

4. 升级了我们的正则表达式库。新版PCRE加入了针对正则表达式的JIT编译器,这为HHVM带来了一个令人兴奋的性能提升。

个人卫生

我确信你在想:”所有的这些收益和统计很很好,但是胡子呢?! ? “没错,你还记得我们再封闭开发前的博文:”剃须即失败”。我很高兴的宣告,我们在封闭开发中同样成功地维持一个最低限度的面部卫生。这里有一些图片来证明这一点。

HHVM团队人手一把剃须刀,准备对面部做清理

我们达到目标了么?

还记得我们在前文提到的成功三要素么?

  • 1. 对21款开源框架做测试后,我们是否达到了平均单测通过率为99%的目标。
  • 2. 我们是否获得了15%的性能提升收益。
  • 3. 团队成员是否能坚持三周不刮胡子。

答案是:

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

未来(2014)

性能改进将永远是HHVM团队关注的核心。兼容性优先级将为1A。我们非常关心开源和PHP社区。我们将在2014年竭尽全力让HHVM在性能与兼容性两方面成为一流,让越来越多得开源项目及框架的单元测试(被)通过。大规模的真实php代码测试。请继续关注我们的进展和计划。最后,祝大家新年快乐。

原文链接: HHVM   翻译: 伯乐在线TechZi
译文链接: http://blog.jobbole.com/58097/

[翻译] Facebook HHVM 团队封闭开发三周成果展的更多相关文章

  1. bug终结者 团队作业第三周

    bug终结者 团队作业第三周 团队展示 队名 bug终结者 队员风采: 杨京典 20162302 风格:先构建框架,在一 一实现,在实现的过程中不断测试和修改. 擅长的技术:拆分问题,使用相对简单的思 ...

  2. 2017-2018-1 Java演绎法 第三周 作业

    团队任务:团队展示与选题 团队展示 队员学号及姓名 学号 姓名 主要负责工作 20162315 马军 日常统计,项目部分代码 20162316 刘诚昊 项目部分代码,代码质量测试 20162317 袁 ...

  3. android组团开发站立会议第三周第一次会议

    会议时间:组队开发第三周  星期一   开始时间晚上9:30-10:00 会议地点:学一食堂 二楼 到会人员:李志岩  王亚蕊 安帅 薛禄坤 张新宇 孙存良 会议概要:              1. ...

  4. “Hello World!”团队第三周召开的第二次会议

    今天是我们团队“Hello World!”团队第三周召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 ...

  5. “Hello World!”团队第三周召开的第三次会议

    今天是我们团队“Hello World!”团队第三周召开的第三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码地址 ...

  6. "Hello World"团队召开的第三周第七次会议

    今天是我们团队“Hello World!”团队召开的第三周的第七次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时 ...

  7. "Hello World"团队召开的第三周第六次会议

    今天是我们团队“Hello World!”团队召开的第三周的第六次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时 ...

  8. “Hello World!”团队第三周召开的第一次会议

    今天是我们团队“Hello World!”团队第三周召开的第一次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时间 ...

  9. JavaEDU614 团队第三周项目总结

    JavaEDU614 团队第三周项目总结 本周,根据项目计划完成模块的设计代码 本项目主要是完成俄罗斯方块的基本操作.用户可以自己练习和娱乐.需要满足以下几点要求. (1)界面控制游戏开始.暂停和结束 ...

随机推荐

  1. mysql数据库int(5)以及varchar(20)长度表示的是什么?

    在mysql5.x版本的数据库中: int类型数据的字节大小是固定的4个字节: 但是int(5)和int(11)区别在于,显示的数据位数一个是5位一个是11位,在开启zerofill(填充零)情况下, ...

  2. Ubuntu使用crontab 使用举例

    除了这些固定值外,还可以配合星号(*),逗号(,),和斜线(/)来表示一些其他的含义:     星号          表示任意值,比如在小时部分填写 * 代表任意小时(每小时)   逗号      ...

  3. 第 2 章 Python 语言入⻔

    目录 2.1低而长的学习曲线 2.2Python的优势 2.3在你的计算机中安装Python 2.4如何运行Python程序 2.5文本编辑器 2.6寻求帮助 Python语言是一种流行的编程语言,在 ...

  4. ie浏览器float兼容性

    在最近的项目中,遇到label.input.和button显示同一行,需求如下 实现代码,框架为react.js <label class="formGrid__label requi ...

  5. Dreamweaver Flash Photoshop网页设计综合应用 (智云科技) [iso] 1.86G

    全书共15章,主要包括网页制作基础.Dreamweaver CC网页制作.Photoshop CC网页图像设计.Flash CC网页动画设计以及综合案例实战5个部分.通过本书的学习,不仅能让读者学会三 ...

  6. C# 字符串转JSON

    一.简单小结 C# 中 String 转 JSON var items = JsonConvert.DeserializeObject<class>(stringJSON); 这里的 cl ...

  7. bbc--平台点击进入详情页配置

    路径: 配置方式: $finderview = 'detail_base'; $arr = array( 'app'=>$_GET['app'], 'ctl'=>$_GET['ctl'], ...

  8. SAS笔记(6) PROC MEANS和PROC FREQ

    PROC MEANS和PRC FREQ在做描述性分析的时候很常用,用法也比较简单,不过这两个过程步的某些选项容易忘记,本文就梳理一下. 在进入正文前,我们先创建所需的数据集TEST_SCORES: D ...

  9. How to modify rosbag?如何修改rosbag?

    Ubuntu16.04,kinetic 本文示例修改使用rosbag中的frame id 在http://wiki.ros.org/bag_tools中,能找到 change_camera_info. ...

  10. CF70D Professor's task(动态凸包)

    题面 两种操作: 1 往点集S中添加一个点(x,y); 2 询问(x,y)是否在点集S的凸包中. 数据保证至少有一个2操作, 保证刚开始会给出三个1操作, 且这三个操作中的点不共线. 题解 动态凸包板 ...