PHP

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

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

我的最終目標是 PHP 中沒有任何一行是我所撰寫的程式,而開發者應該也以此為目標。──PHP 之父 Rasmus Lerdorf

一个 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 中没有任何一行由他所撰写的程式码,「任何在成长中的项目都不应该由一个开发者主导,老旧的代码应该被新的替换。」而他认为,其他开发者应该以此为目标。