[转]徐汉彬:PHP7和HHVM的性能之争

【导读】徐汉彬曾在阿里巴巴和腾讯从事4年多的技术研发工作,负责过日请求量过亿的Web系统升级与重构,目前在小满科技创业,从事SaaS服务技术建设。最近,PHP7和HHVM的性能之争成为了一个讨论热点,它们都在提升PHP执行性能方面取得了突破性的进展。这篇文章,参考了两个社区的技术新进展,为大家科普和介绍它们的性能之争。 

[转]徐汉彬:PHP7和HHVM的性能之争 

在PHP程序员中,曾经流传着一个段子:

某女:你能让这个论坛的人都吵起来,我就跟你吃饭。 
PHP程序员:PHP是世界上最好的语言! 
某论坛炸锅了,各种吵架……  
某女:服了你了,我们走吧! 
PHP程序员:今天不行,我一定要说服他们,PHP必须是最好的语言。

好了,我们言归正传,语言本身无分好坏,只是在各自使用的场景中解决不同的问题。互联网的时代车轮是很快的,随着移动互联网的到来,在短短四年多的时间里,移动端技术发展横扫全球。与此同时,各种语言群雄并起,而昔日辉煌的PHP从原来的编程语言的榜单看,下降到第六位(2014年12月榜单)。于是,唱衰PHP的声音此起彼伏。

[转]徐汉彬:PHP7和HHVM的性能之争 

这个结构体将会占据远比C变量多得多的内存,PHP中定义方式如下:

$a = 200;//这变量将实际占用对比C变量很多倍的存储空间。

其实对PHP来说,无论存储什么类型的数据,都是用上述“通杀”的结构体实现。为了兼容PHP程序员的变量类型“乱入”,PHP做到了对开发者的友好,但是对执行引擎很残酷。单个变量内存消耗可能还不明显,一旦用到PHP的数组等,则复杂度指数上升(数组的实现是HashTable)。然后,Zend引擎执行时,将这些PHP代码编译为opcode(PHP的中间字节码,格式有点类似于汇编),由Zend引擎逐行解释执行。

无论是字符串的连接操作,还是数组的简单修改等,几乎都是“PHP程序员一句话,Zend引擎跑断腿”的节奏。因此,同样的操作,对比C来说,PHP消耗了更多的CPU和内存等系统资源。除此之外,还有内存自动回收、变量类型判断等等,都会增加系统资源的消耗。

例如,我用纯PHP实现的快速排序函数和原生sort函数,排序10000个整型数字,来做一个耗时对比,结果如下:

[转]徐汉彬:PHP7和HHVM的性能之争 

通常情况下,PHP执行效率的排行是:

  1. 最快的是PHP语言结构(isset、echo等),PHP语言的一部分(它们根本不是函数)。
  2. 然后比较快的就是PHP的原生和拓展函数。PHP拓展,基于Zend API之上,用C实现的功能,执行效率和C++/Java是属于同一个数量级的。
  3. 真正慢的就是,我们通过PHP自己写的代码和函数。例如,假如我们使用的比较重的纯PHP实现的框架,因为框架本身的模块很多,所以,会明显拖累语言层面的执行效率,同时占据更多的内存。(国内的Yaf框架,以拓展的方式实现,因此执行效率远快于纯PHP写的框架)

[转]徐汉彬:PHP7和HHVM的性能之争 

普通的PHP代码,因为无法固定变量的类型,需要额外添加判断类型的逻辑代码,这样PHP代码是不利于CPU执行和优化的。因此,HHVM通常需要用到Hack写法(为了兼容某种特性而额外添加的技巧性质的代码)的PHP代码来“配合”,就是为了让变量类型固定,方便虚拟机编译执行。PHP追求以一种形式来容纳一切类型,而Hack则可以将被容纳的一切标记上确定的类型。

PHP代码的Hack写法的例子:

[转]徐汉彬:PHP7和HHVM的性能之争 

不过,从具体业务场景来看,HHVM和PHP7的差距并没有那么大,以WordPress开源博客首页为测试场景的结果中,他们目前的差距并不明显。 

[转]徐汉彬:PHP7和HHVM的性能之争 

因为项目仍然处于开发中的原因,从表格中,可以看见的特性描述都比较模糊。肯定有更多的其他特性,只是尚未公布。下面的这些,是从PHP社区看见的,因为PHP7是一个开发中的项目,下面的这些也不一定准确,不过,不妨碍我们一起来看看。

  1. PHPNG(PHP next generation,下一代PHP),对Zend执行引擎本身的各种性能优化,其中JIT,可能会实现在Zend Opcache组件中。
  2. AST(Abstract Syntax Tree,抽象语法树),目的是在PHP编译过程引入一个中间件,替代直接从解释器吐出opcode的方式。让解释器和编译器解耦,可以减少大量Hack代码,同时,让实现更容易理解和维护。
  3. uniform variable syntax(统一变量语法),引入一种内部一致和完整的变量语法,让PHP的解析器更完整地支持各种类型的变量。部分变量的用法需要调整,例如变量的变量$$a等。
  4. 支持integer semantics(整型语义),例如NaN、Infinity、<<、>>,修正list()的一致性等等。

上面的特性中,最令人期待的就是PHPng的性能优化,PHP社区已经放出了一些性能的测速数据。从数据上看,PHPng的执行性能比起项目启动之初,已经有接近1倍的提升。这个成绩已经非常不错,况且,最关键的是PHP7的优化计划还有很多尚未完成。等到都全部完成了,相信我们可以看见一个性能更高的PHP7。

这测速数据是来自于PHP社区(wiki.php.net/phpng),截取了一部分的数据:

[转]徐汉彬:PHP7和HHVM的性能之争 

简单翻译下:

  • 综合测试速度提升35%。
  • 在实际应用场景有20%-70%的速度提升(WordPress首页有60%的提升)
  • 更少的内存消耗
  • 支持大部分常用的SAPIs
  • 支持大部分的PHP拓展绑定到资源分配(69个完成,6个待迁移)
  • 提供堪比HHVM3.3.0的执行速度

2. PHP的弱类型争议

PHP被争议的特点很多,但是随着语言版本的发布和完善,功能和特性方面的批评开始变少了。但是,PHP的“弱类型”特性,却明显受到更多的争议,从HHVM通过Hack的方式直接“去掉”了“弱类型”特性可以看出,HHVM并不喜欢“弱类型”特性。然而,在我们很多PHP程序员的眼中,这却是PHP的重要优点之一。PHP里的变量被设计得随性和飘逸,海纳百川,一切皆可包容,不是让语言显得更为简单吗/p>

实际上,有些人认为它是个严重的问题,对于“弱类型”的批评观点大致如下:

  1. 在“严谨”的语言中,通常是预先定义好一个变量的类型,自始至终,变量的类型是固定的,使用范围也是固定。而PHP的变量,通常我们只能看见它名字,类型大部分都不可以预先定义,并且还可以随意改变。(内存分配不好管理)
  2. 为了兼容弱类型特性,PHP需要实现大量兼容代码,包括类型判断、类型转换、存储方式等,增加了语言内部的复杂度。(执行效率低下)
  3. 变量的类型是不可控的,在执行过程中存在大量的“隐性类型转换”,容易产生不可预知的结果。(这里的确需要强调,PHP的类型转换是个必须掌握的点,各种类型的互相转换的可能会产生很多问题,尤其是初学PHP的同学哈)

他们认为,这些都不符合“所见即所得”的简单性,而语法严谨的语言更高效率,也更容易“理解”。

受到类似批评的还有Javascript等语言,因为它在这个问题上的表现是一样的。但是,一门语言最终被大规模使用,必然有它们的道理。PHP成为Web服务开发的首选脚本语言,Javascript则直接称霸Web前端领域,能走到这一步都不可能是偶然因素,开发者们用脚投票选择了它们。编程语言是人类和机器沟通的桥梁,终极追求是实现“人人皆可编程”的宏伟目标。

纵观语言发展历史,从0和1的机器码开始,到汇编语言,然后到C语言,再到动态脚本语言PHP。执行效率呈指数下降,但是,学习门槛也呈指数降低。PHP语言不仅屏蔽了C的内存管理和指针的复杂性,而且更进一步屏蔽了变量类型的复杂性。提升了项目开发的效率,降低了学习的门槛,但同时牺牲了一定的执行性能。然后,HHVM的Hack给我们一种“回归原始”的感觉,重新引入了变量的复杂性。当然,不同的语言解决不同场景下的问题,并不能够一概而论。

[转]徐汉彬:PHP7和HHVM的性能之争 

小结

HHVM对PHP的性能提升,让人眼前一亮,而磨刀霍霍的PHP7则让人万分期待。两者都是极其优秀的开源项目,都在不断前进和发展中。就目前而言,因为距离PHP7正式版的发布还有比较长的一段时间,所以当前性能优化方案的首选当然是HHVM。不过,就我个人而言,我比较看好PHP7,因为它更能做到PHP代码的向下兼容。如果两者性能相差不大,我会选择简单的那个。

参考资料:

  • https://wiki.php.net/rfc/php7timeline
  • https://wiki.php.net/phpng
  • http://hhvm.com/

文章来源:http://www.csdn.net/article/2014-12-25/2823234

来源:黑夜路人

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2014年11月26日
下一篇 2014年11月26日

相关推荐