带你了解PHP7 性能翻倍的关键


Posted in PHP onNovember 19, 2015

20岁老牌网页程序语言PHP,最快将在10月底释出PHP 7新版,这是十年来的首次大改版,最大特色是在性能上的大突破,能比前一版PHP 5快上一倍,PHP之父Rasmus Lerdorf表示,甚至能比HHVM虚拟机下的PHP程序性能更快。

HHVM 是脸书为自家网站特性而量身客制的PHP优化机制,不见得适用任何网站。但Rasmus Lerdorf表示,新版目标之一就是要让任何网站开发者,就连使用开发框架Drupal、开源电子商务系统Opencart时,都能有不输使用HHVM 技术的性能。在新版发表前夕,他也趁来台参加PHPConf Taiwan年会时,分享PHP 7性能大突破的关键。

一个20年来历经了多 次改版和无数次优化的成熟语言,还能有性能提高一倍的突破绝非易事,Rasmus Lerdorf坦言,不像一般新项目多半容易找出许多改进空间,新版PHP并非修改部分程序就达到了如此的成果。反而是,透过大量细节优化和性能累加 后,PHP 7才具备了不输HHVM的执行性能。

Rasmus Lerdorf与PHP核心贡献团队花了许多心力减少程序运作时搬动的内存位数,由此加速执行的性能。例如,PHP中储存变量的数据架构zval从24位 缩减至16位、Hashtable从72位减少至56位,并检视PHP中的函式,思考有无任何改进性能的空间。

除了从减少内存的使用着手 外,Rasmus Lerdorf更检视CPU的Cache line的运作原理,了解程序代码如何与CPU互动、编译程序如何在新CPU架构下编译程序代码等细节,确保PHP 7的程序代码符合现代CPU的架构。虽然每个项目的优化对性能贡献都低于0.5%,但由于优化的项目很多,或是某项改善的功能会被应用程序反复呼叫,整体 修正的综效结果就能有如此大的进展。

受HHVM刺激,决定打造兼具性能与功能的PHP

Facebook为了优化PHP运作,搭配JIT编 译而打造出虚拟机HHVM。而HHVM虽然拥有快速的执行性能,其为特定用途优化的设计,只能满足小部分的开发者。反之,Rasmus Lerdorf除了想提升PHP的性能表现外,也想要同时满足高端使用者以及业余使用者的需求,让PHP 7成为兼备性能表现及通用功能的程序语言。

然而,开发符合市场上少部分人使用的程序语言并不是难事,但是PHP项目瞄准许多对象,必须同时符合业余使用者及专业开发者需求的原则下,开发难以面面俱 到,因为总是会有部分族群的需求无法被满足,「这就像拿水管大范围的喷洒,而每个人衣服都会被水沾湿一点,但是不会有人的衣服完全湿透。」Rasmus Lerdorf比喻。

不使用外挂框架的PHP的运算性能表现都很优异,但是受到外加框架的影响,原本可以在数秒内处理上千个网页要求的 PHP,性能大幅下降,变为只能处理数十个要求。Rasmus Lerdorf表示,在HHVM出现之前,相较于对PHP性能表现的要求,使用者比较在意PHP能否降低网页开发的难度,而这些框架能让开发者的工作变得 比较简单。但是在Facebook推出HHVM后,引出许多重视PHP性能表现的使用者,让Rasmus Lerdorf意识到许多使用者有性能表现的需求。他开始思考如何将HHVM的JIT架构与PHP融合。

但Rasmus Lerdorf表示,PHP与HHVM两者在架构设计上相当不同,例如,HHVM的多线程架构并不是很稳固。此外,HHVM的可移植性并不佳,离可以在 Windows平台上运作还有很大一段路,而PHP有很多开发者在Windows环境开发,而HHVM无法照顾到那些使用者。

Rasmus Lerdorf表示,他不能放弃PHP的主要架构,虽然他们曾经考虑过融合两者,但是,HHVM在使用上有很多的限制。虽然HHVM对Facebook及 许多开发者是非常好的工具,但对于PHP项目来说,HHVM的使用范畴还不够宽广,只能符合Facebook或是Wikipedia等特定项目的需求。

非强型别语言的PHP,导入JIT是难上加难

然而,在PHP中加入JIT编译是件非常困难的事情。Rasmus Lerdorf表示,JIT必须学会辨认程序的运作模(Patterns),例如了解哪些部份为重要的程序代码,并且在程序运作前,预测程序被呼叫的时 机,或是哪些部分的程序会呼叫。

Rasmus Lerdorf比喻,在许多汽车中,JIT必须能预测哪部分的车子会右转、哪部分的车子会左转或是某些颜色汽车会直行,「而JIT必须要全部预测正确,否则性能会大大的降低。」但是,如果预测正确,程序执行性能则会大大提升。

在一般的程序语言的编译中加入JIT已属不易,Rasmus Lerdorf表示,由于PHP的动态属性(dynamic)让加入JIT是难上加难。他举例,开发者宣告参数$a值为1,但不代表程序所有的$ a的值都为1,由于PHP中参数值可以很轻易地重新定义。在C语言中,当开发者宣告参数a为整数,则a永远为整数。如果程序中有任何地方宣告a是整数以外 的类型,连编译都无法执行。而因为C语言此种强型别的程序语言,「JIT可以预测变量a为整数,但是在PHP中,我们没有这种奢侈。」他解释,HHVM的 做法为当JIT得知a是整数型别后,则假设a永远为整数。

而HHVM为了在使用JIT编译,某种程度上受限了PHP的发展。HHVM的用户 必须清楚宣告变量的性质,但是使用PHP的开发者,可以先宣告没有性质的类别(Class),后续再指定类别的变量属性。「在没有任何限制下,将JIT加 入PHP是我们要做的事。」他表示,PHP必须顾及Wordpress、Drupal等框架的开发者,不能任意停止对此些框架的支持。故与HHVM相 比,PHP在打造JIT的条件限制更多。

但是,「这不代表我们不能做JIT。此外,我们也要控制PHP的发展走向。」Rasmus Lerdorf表示。

目前,PHP核心贡献者之一的Dmitry Stogov开发一个原型JIT,并且使用某些实验性的应用程序去测试运作。Rasmus Lerdorf表示,如果将此JIT用于执行某些重复性的运算或是循环程序,得以让PHP 7性能又再快上10倍。

不过他也坦承,当此实验性的JIT用于Wordpress时,并未得到任何加速效果,「我们想要打造的JIT不是要在大学课本上学到的东西,而是能在真实世 界中运作的JIT。」他表示。因为PHP一直都抱持如此的理想,试图解决人们生活中的问题,并且能真实世界中在线环境中运作,而不只是存在课本中的理论。

Rasmus Lerdorf表示,在PHP刚问世时,他每天至少花16个小时开发PHP。但目前他已经逐渐减少投入开发,转而投注心力在世界各地宣传及演讲。他打趣地 表示:「与其自己开发,不如激励远比我聪明,又愿意一天花十八小时写程序的人去开发PHP。」他表示,他的最终目标是PHP中没有任何一行由他所撰写的程 序代码,「任何在成长中的项目都不应该由一个开发者主导,老旧的程序代码应该被新的程序代码替换。」而他认为,其他开发者应该以此为目标。

PHP 相关文章推荐
使用XDebug调试及单元测试覆盖率分析
Jan 27 PHP
php获取百度收录、百度热词及百度快照的方法
Apr 02 PHP
大家须知简单的php性能优化注意点
Jan 04 PHP
Windows下PHP开发环境搭建教程(Apache+PHP+MySQL)
Jun 13 PHP
py文件转exe时包含paramiko模块出错解决方法
Aug 12 PHP
PHP7匿名类用法分析
Sep 26 PHP
PHP中用mysqli面向对象打开连接关闭mysql数据库的方法
Nov 05 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
Dec 02 PHP
详解Yii2 rules 的验证规则
Dec 02 PHP
ThinkPHP5.0 图片上传生成缩略图实例代码说明
Jun 20 PHP
php中访问修饰符的知识点总结
Jan 27 PHP
php策略模式简单示例分析【区别于工厂模式】
Sep 25 PHP
php curl模拟post请求和提交多维数组的示例代码
Nov 19 #PHP
phpStudy访问速度慢和启动失败的解决办法
Nov 19 #PHP
标准版Eclipse搭建PHP环境的详细步骤
Nov 18 #PHP
WordPress网站性能优化指南
Nov 18 #PHP
php+ajax实现无刷新分页
Nov 18 #PHP
如何使用php脚本给html中引用的js和css路径打上版本号
Nov 18 #PHP
php生成唯一数字id的方法汇总
Nov 18 #PHP
You might like
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
2013/06/20 PHP
php class类的用法详细总结
2013/10/17 PHP
PHP对文件进行加锁、解锁实例
2015/01/23 PHP
深入理解PHP内核(二)之SAPI探究
2015/11/10 PHP
Symfony2创建基于域名的路由相关示例
2016/11/14 PHP
PHP实现redis限制单ip、单用户的访问次数功能示例
2018/06/16 PHP
php实现的rc4加密解密类定义与用法示例
2018/08/16 PHP
使用Git实现Laravel项目的自动化部署
2019/11/24 PHP
关于可运行代码无法正常执行的使用说明
2010/05/13 Javascript
jQuery.each()用法分享
2012/07/31 Javascript
Extjs4 类的定义和扩展实例
2013/06/28 Javascript
jQuery子属性过滤选择器用法分析
2015/02/10 Javascript
JS实现网页滚动条感应鼠标变色的方法
2015/02/26 Javascript
js中的内部属性与delete操作符介绍
2015/08/10 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
angular6根据environments配置文件更改开发所需要的环境的方法
2019/03/06 Javascript
vue中使用rem布局代码详解
2019/10/30 Javascript
JS数组Reduce方法功能与用法实例详解
2020/04/29 Javascript
python的id()函数解密过程
2012/12/25 Python
Python中的yield浅析
2014/06/16 Python
python ansible服务及剧本编写
2017/12/29 Python
PyTorch 1.0 正式版已经发布了
2018/12/13 Python
Python3.6.x中内置函数总结及讲解
2019/02/22 Python
python将视频转换为全字符视频
2019/04/26 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
keras多显卡训练方式
2020/06/10 Python
Python爬虫实现自动登录、签到功能的代码
2020/08/20 Python
python正则表达式re.match()匹配多个字符方法的实现
2021/01/27 Python
基于HTML5 Canvas的3D动态Chart图表的示例
2017/11/02 HTML / CSS
玩具反斗城美国官网:Toys"R"Us
2016/09/17 全球购物
美国CVS药店官网:CVS Pharmacy
2018/07/26 全球购物
幼儿园园长岗位职责
2013/11/26 职场文书
乡党政领导班子群众路线教育实践活动个人对照检查材料
2014/09/20 职场文书
2015年爱牙日活动总结
2015/03/23 职场文书
历史名人教你十五个读书方法,赶快Get起来!
2019/07/18 职场文书
Python实现为PDF去除水印的示例代码
2022/04/03 Python