【问题标题】:Does PHP interpreter eliminate dead conditionals?PHP解释器是否消除了死条件?
【发布时间】:2016-02-23 20:59:28
【问题描述】:

在将PHP源代码转换为操作码之前,有没有消除死条件的优化过程?

例子:

<?php

if (false) {
  echo 'false';
}
echo 'true';

它是否只转换为echo 'true';

如果答案是肯定的,PHP可以处理以下哪种情况?

if(false);               //Explicit boolean
$true = true; if($true); //Variable that was assigned a constant boolean
if(ClassName::Constant); //Class constant
if(1>2);                 //Constant value expression

如果存在版本特定的差异,请多多包涵。

【问题讨论】:

  • 公平地说 php 确实尝试在运行时优化代码
  • 优化的大问题是变量是typed dynamically,因此可以在不同的时间(并且经常这样做)保存完全不同的东西。难以优化。
  • 是的,只是想说php尝试优化代码,但任务更小
  • PHP 的 OpCache 可以在字节码层面进行优化,但 PHP 代码本身的优化取决于开发者

标签: php php-internals


【解决方案1】:

不,它不会消除任何代码。

【讨论】:

    【解决方案2】:

    是的,无法访问的块将被 opcache 优化器的“块传递”部分消除。对于您的特定示例:

    if(false);               // 1. Will be optimized
    $true = true; if($true); // 2. Will NOT be optimized
    if(ClassName::Constant); // 3. Will MAYBE be optimized
    if(1>2);                 // 4. Will be optimized
    

    示例 2 不会被优化,因为我们目前没有对“真实”变量执行常量传播。目前优化器不使用 SSA 形式,因此我们没有信心执行这种类型的优化。一旦我们有了它,我们就可以使用 SCP / SCCP 通行证来覆盖它。

    可以优化示例 3,具体取决于定义 ClassName 的位置。一般来说,如果它要么是不可重新绑定范围内的self,要么是在同一个文件中定义的类,它都会被优化。此外,常量的值也必须是静态可计算的常量表达式。

    无法访问的代码消除是作为block_pass.c 的一部分实现的。

    【讨论】:

    • 示例 3(错误数字 ;-))将被优化,以防在常量使用之前加载类的每种情况下都没有加载 opcache。此外,它不是同一个文件,但 self 或类名指的是当前定义的类。
    • @bwoebi 如果没有加载 opcache,我不相信我们会删除无法访问的块。而且 opcache 也应该替换同一个文件中的类常量,即使它不是当前类(不像编译器中的常量折叠)。
    • 谢谢,他们的关键字“block pass”帮助我找到了相关的源代码,我更新了你的答案并包含了一个指向源文件的链接,这样每个人都可以从中受益
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多