PHP 7.4 上的 Preloading 和 JIT(将在 PHP 8 上发布)有什么区别
What is the difference between Preloading on PHP 7.4 and JIT (which is going to be released on PHP 8)
我正在阅读有关 Preload 的文章并对此感到非常兴奋,但是(正如我通过在 Google 上搜索更多内容所了解的那样)它们在我看来似乎具有相同的定义:
预加载:在服务器启动时加载已编译的PHP文件,并使所有定义的类和函数在未来请求的上下文中永久可用(据我了解 here)
JIT:在 运行 时而不是在执行
之前编译文件
哪个对性能影响更大?特别是框架
这里的混淆是在“编译”的两种不同含义之间;或者,实际上,相同的含义 - 将高级程序转换为一组较低级别的指令 - 对同一程序应用两次。
从PHP 4开始,人类编写的PHP代码已经被自动编译成一种更抽象的语言,称为“操作码”。这些充当“虚拟机”的指令,但仍然非常高级:每个操作代码触发 Zend 引擎中的整个子例程。
PHP 中包含的 OpCache 扩展自版本 5.5 以来不仅缓存这些操作代码以节省重新编译的时间,它还通过操作它们执行大量优化。预加载是该机制的一部分:它 运行 编译和优化步骤,并保存操作码以供多个 PHP 进程重用。
但是,这些操作码距离 CPU 实际要 运行 的代码还有很长的路要走。执行它们的虚拟机在技术上是一个解释器,通过指令列表工作,并执行多个步骤,即使是像 $x + $y
.
这样简单的事情。
PHP8 中 JIT 的基本思想是用第二个编译器来补充解释器——这一次,将 从 操作码编译成实际的机器指令。更具体地说,JIT 编译器查看一段代码 ,因为它 运行s(因此称为“及时”),并生成一组 CPU 指令实施它。
现在您可能想知道为什么我们不尽早执行此操作 - 准时制似乎是预加载的对立面!优点是 JIT 编译器可以查看代码实际 的使用方式,而不是它可能 的所有可能使用方式。查看 $x + $y
的操作码的解释器必须考虑这样一个事实,即 每次代码 运行s,这些变量可能是整数、浮点数、字符串,或者 +
需要抛出错误的东西。 JIT 编译器可以看到 运行ning 程序 经常 将它们都作为整数,并为该场景 编译一些快速代码 。当出现其他情况时,JIT 编译器只是交还给普通的解释器。
我正在阅读有关 Preload 的文章并对此感到非常兴奋,但是(正如我通过在 Google 上搜索更多内容所了解的那样)它们在我看来似乎具有相同的定义:
预加载:在服务器启动时加载已编译的PHP文件,并使所有定义的类和函数在未来请求的上下文中永久可用(据我了解 here)
JIT:在 运行 时而不是在执行
之前编译文件哪个对性能影响更大?特别是框架
这里的混淆是在“编译”的两种不同含义之间;或者,实际上,相同的含义 - 将高级程序转换为一组较低级别的指令 - 对同一程序应用两次。
从PHP 4开始,人类编写的PHP代码已经被自动编译成一种更抽象的语言,称为“操作码”。这些充当“虚拟机”的指令,但仍然非常高级:每个操作代码触发 Zend 引擎中的整个子例程。
PHP 中包含的 OpCache 扩展自版本 5.5 以来不仅缓存这些操作代码以节省重新编译的时间,它还通过操作它们执行大量优化。预加载是该机制的一部分:它 运行 编译和优化步骤,并保存操作码以供多个 PHP 进程重用。
但是,这些操作码距离 CPU 实际要 运行 的代码还有很长的路要走。执行它们的虚拟机在技术上是一个解释器,通过指令列表工作,并执行多个步骤,即使是像 $x + $y
.
PHP8 中 JIT 的基本思想是用第二个编译器来补充解释器——这一次,将 从 操作码编译成实际的机器指令。更具体地说,JIT 编译器查看一段代码 ,因为它 运行s(因此称为“及时”),并生成一组 CPU 指令实施它。
现在您可能想知道为什么我们不尽早执行此操作 - 准时制似乎是预加载的对立面!优点是 JIT 编译器可以查看代码实际 的使用方式,而不是它可能 的所有可能使用方式。查看 $x + $y
的操作码的解释器必须考虑这样一个事实,即 每次代码 运行s,这些变量可能是整数、浮点数、字符串,或者 +
需要抛出错误的东西。 JIT 编译器可以看到 运行ning 程序 经常 将它们都作为整数,并为该场景 编译一些快速代码 。当出现其他情况时,JIT 编译器只是交还给普通的解释器。