PHP8就要来了,它将在年11月26日发布,目前PHP8处于功能冻结状态,不再添加任何新功能。
随着这个大版本发布日期越来越近,人们也正在期待着它能给开发者更多的惊喜,能让大家的生活更轻松。本文就来探寻关于PHP8的技术创新和给开发者带来的意义。
背景
计算机本身并不懂得编程语言,它只懂得二进制指令,这些指令人类很难用手工编写。而编程语言就是一种将人类可读的语言翻译成计算机能理解的指令,这些编程语言有很多种,例如PHP,Rust等。
最简单且效果最好的方法是将人性化的语言代码“提前“(AOT)编译为CPU理解的指令,这些指令被以二进制形式保存在独立的文件里。哪些语言会用到这种方法呢?有C,C++还有Rust等等。表现稍微差强人意的,但更容易编写的是解释性语言,俗称叫脚本语言。
在这种语言中,有一个被称为”解释器“的程序,当执行脚本时,它将源代码中的每个指令转换为机器代码。PHP3.0使用的是这种方式,和现在的PHP相比,它的执行就比较慢。
另一种方式是用”虚拟机“。虚拟机的工作方式与解释器相类似,但是是虚拟机会将源代码转换为更简单的语言——一种较低级的脚本语言,可以更快的解释完成。
这种虚拟机的方式在各种编程语言中就非常流行,它在复杂度、容易开发以及性能之间取得了非常好的平衡。
这种转换为”简单语言“的行为是提前发生的,比如Java、C#和Go语言,还有即时发生的,如PHP、Python以及JavaScript。Java把这种中间简化的版本称为”字节码“,PHP称之为”操作码“,两者是一回事。
运行环境
编译的最新趋势是”即时“编译器或JIT。JIT编译器从中间码开始解析,将其即时转换为机器代码,存储并执行。JIT编译器非常复杂,为了要获得良好的性能,通常必须将语言的某些东西分别编译为机器代码,哪此不用编译。转换为机器代码并不代表会快,具体还取决于代码的细节和所涉及的语言。另外,把简化的代码转换为本地代码的过程比运行并完成的花费时间要更多时间。
所以,大多数的JIT编译器会在代码运行时进行分析,确定哪些部分最有意义,然后确切编译。从理论上的结果是,程序在运行时会变快很多,而且虚拟机中的JIT编译器会知道哪些代码仍需要优化。
Java是将JIT集成到虚拟机的第一个被广泛使用的语言。如今,大多数主要的JavaScript引擎也都使用此技术。而PHP8中,正式引入JIT虚拟机。
关于PHPJIT
PHP的新JIT其实已经存在很长时间了,也就是开发了几年,在PHP7.4中已经发布。对PHP中启用JIT引擎是PHP8进行大规模修改的动力,JIT已经使PHP7的性能大幅度提升。
PHPJIT被设计成操作码缓存扩展,这意味着创建PHP进程或运行时,可以用php.ini的参数来激活或停用它。
正确的配置
默认情况下,JIT扩展是禁用的,在php.ini中的参数如下::
opcache.jit_buffer_size
将其值改为非零值即可,这个值表示优化机器码占用内存的空间。并不越多越好,JIT会花费很多时间来分析代码的真正受益之处。
还有一个重要配置是opcache.jit,这控制JIT活动的4个级别。这些级别用4个数字表示,PHP8的RFC文档有更多的信息,此处不展开详述。
JIT也没有标准的最佳配置,与类似的高级工具一样,开发者需要对自己的应用大胆实验,对其值进行不断的微调。
JIT会带来什么
JIT是不是真的提高性能。与往常一样,可预测的答案是”取决于“。对于Web应用程序,也许是某种方式的提升。对于生态系统而言,这是巨大的改变。
PHP被设计成在非共享的配置中运行,处理完每个请求后,程序就会终止运行。这给JIT很少的时间来分析和优化代码。特别是因为典型的Web请求中,大多数代码仅执行一次,以线性方式处理。同样,这些应用程序中的大多数是I/O操作,JIT无法提供到帮助。
在如今不考虑用PHP的用例中,JIT可能真正有用的地方,包括持久的守护程序,解析器,机器学习和其它长时间运行的CPU密集计算的地言,会展现JIT的优势,就像PHP7.4中的FFI外部功能接口。
PHPJIT是为PHP编写的解析器,之前我们也提到过NikitaPopov,被现今很多静态分析(PHPStan: