[翻译] Facebook HHVM 团队封闭开发三周成果展
本人翻译的一篇文章,首发于伯乐在线。
【补充信息】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 |
77.94 |
100 |
22.06 |
|
88.24 |
100 |
11.76 |
|
98.79 |
98.89 |
0.10 |
|
92.4 |
99.95 |
7.55 |
|
98.61 |
100 |
1.39 |
|
100 |
100 |
0 |
|
100 |
100 |
0 |
|
94.09 |
97.92 |
3.83 |
|
99.23 |
100 |
0.77 |
|
97.66 |
98.74 |
1.08 |
|
98.91 |
99.98 |
1.07 |
|
100 |
100 |
0 |
|
Fatal |
92.66 |
92.66 |
|
94.58 |
99.5 |
4.92 |
|
96.15 |
94.16 |
-1.99 |
|
96.29 |
97.03 |
0.74 |
|
100 |
100 |
0 |
|
86.53 |
96.67 |
10.14 |
|
99.23 |
100 |
0.77 |
|
78.08 |
99.11 |
21.03 |
|
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链接 |
描述 |
Support different style error messages |
|
Support the HHVM requirement of implementing methods of interfaces |
|
Support the definition usort() on equal values |
|
Support our parallel testing framework |
|
Support a string check in hash_hmac |
|
Better use of strings instead of large integers in certain parsing scenarios |
|
Support HHVM in PHP_BINARY checks |
|
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 团队封闭开发三周成果展的更多相关文章
- bug终结者 团队作业第三周
bug终结者 团队作业第三周 团队展示 队名 bug终结者 队员风采: 杨京典 20162302 风格:先构建框架,在一 一实现,在实现的过程中不断测试和修改. 擅长的技术:拆分问题,使用相对简单的思 ...
- 2017-2018-1 Java演绎法 第三周 作业
团队任务:团队展示与选题 团队展示 队员学号及姓名 学号 姓名 主要负责工作 20162315 马军 日常统计,项目部分代码 20162316 刘诚昊 项目部分代码,代码质量测试 20162317 袁 ...
- android组团开发站立会议第三周第一次会议
会议时间:组队开发第三周 星期一 开始时间晚上9:30-10:00 会议地点:学一食堂 二楼 到会人员:李志岩 王亚蕊 安帅 薛禄坤 张新宇 孙存良 会议概要: 1. ...
- “Hello World!”团队第三周召开的第二次会议
今天是我们团队“Hello World!”团队第三周召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 ...
- “Hello World!”团队第三周召开的第三次会议
今天是我们团队“Hello World!”团队第三周召开的第三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码地址 ...
- "Hello World"团队召开的第三周第七次会议
今天是我们团队“Hello World!”团队召开的第三周的第七次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时 ...
- "Hello World"团队召开的第三周第六次会议
今天是我们团队“Hello World!”团队召开的第三周的第六次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时 ...
- “Hello World!”团队第三周召开的第一次会议
今天是我们团队“Hello World!”团队第三周召开的第一次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时间 ...
- JavaEDU614 团队第三周项目总结
JavaEDU614 团队第三周项目总结 本周,根据项目计划完成模块的设计代码 本项目主要是完成俄罗斯方块的基本操作.用户可以自己练习和娱乐.需要满足以下几点要求. (1)界面控制游戏开始.暂停和结束 ...
随机推荐
- JAVA基础知识总结3(面向对象)
特点:过程其实就是函数:对象是将函数等一些内容进行了封装 1:将复杂的事情简单化. 2:面向对象将以前的过程中的执行者,变成了指挥者. 3:面向对象这种思想是符合现在人们思考习惯的一种思想. 匿名对象 ...
- koa2,koa1框架安装
koa2版本安装: npm install koa@ -g hello2.js var Koa = require('koa'); var app = new Koa(); app.use(ctx = ...
- 关闭QtCreator的vim风格编辑模式
今天不小心点到了键盘的快捷键Alt+V,使QtCreator进入了vim风格编辑模式,导致快捷键拷贝粘贴都不正常,找了下资料才发现是这个问题.具体操作如下: 打开QtCreator去掉下列位置的勾选或 ...
- C#的常量和变量以及其作用域和命名规范
1.常量:在编译时其值能够确定,并且程序运行过程中值不发生变化的量. 通俗来说,就是定义一个不能改变值的量.既然不能变动值,那就必须在定义的时候初始化. 语法: const 类型名 常量名=常量表达式 ...
- If,for,range混合使用笔记-(VBA视频教程2:使用IF进行逻辑判断)
-- 新建表格:#单元格a1-a100全部等于1的代码 Sub test() Dim i As Integer For i = To Range( Next End Sub -- 新建表格:#单元格a ...
- Yaf + Smarty 整合笔记
Yaf真的是太简单了,简单到使用mvc的时候在view里面需要手写php脚本.因此考虑整合一下smarty模板引擎.随心所欲也正是yaf的魅力 Yaf 安装 这里简单说一下yaf的安装,已经是非常无脑 ...
- Fiddler-抓Android和IOS包
知识:Fiddler能捕获IOS设备发出的请求,比如IPhone, IPad, MacBook. 等等苹果的设备. 同理,也可以截获Andriod,Windows Phone的等设备发出的HTTP/ ...
- Gson本地和服务器环境不同遇到的Date转换问题 Failed to parse date []: Invalid time zone indicator
GoogleGson在处理Date格式时有个小陷阱,在不同环境中部署时可能会遇到问题. Gson默认处理Date对象的序列化/反序列化是通过一个SimpleDateFormat对象来实现的,通过下面的 ...
- AT2672 Coins
传送门 按理说想到转化问题之后就不难了吧,可是我还是不会写 一个很容易想到的转化就是差分,将银币数和铜币数都减去金币数,这样就转化为\(x+y+z\)个钱币选\(y\)个银币和\(z\)个铜币的最大数 ...
- 关于Git的一些操作记录
本文是我的一些记录,不按教学顺序 1.如何添加不上传的文件或文件夹,并且将已经添加到远程库的文件夹删除 操作过程如下: vim .gitignore // 按i进入编辑模式 写入 node_modul ...