PHP引擎是不是优化循环内的匿名函数?

Posted

技术标签:

【中文标题】PHP引擎是不是优化循环内的匿名函数?【英文标题】:Does PHP engine optimize anonymous functions within loops?PHP引擎是否优化循环内的匿名函数? 【发布时间】:2013-08-05 18:13:05 【问题描述】:

我有一个数组,它存储对单个 anonymous function 的多个引用:

$fns = array();
//some code
$fn = function()
    echo 'this is closure 12345... < 67890';
    // etc etc..
;
for($x=12345; $x<67890; ++$x)
    $fns[$x] = $fn;

可以看出,我们只创建了一个匿名函数。

如果我们将函数声明放在循环中会怎样? :

$fns = array();
//some code
for($x=12345; $x<67890; ++$x)
    $fns[$x] = function()
        echo 'this is closure 12345... < 67890';
        // etc etc..
    ;

引擎是否足够聪明,可以识别出只需要创建一个对象?

上面的代码是只创建一个对象还是每次迭代创建一个对象?

(问题针对 HHVM 和 Zend 引擎。)

【问题讨论】:

你分析了吗? 300 个对象不算什么。您甚至可能无法用那几个物体测量差异。除非您开始创建数百万个对象,否则差异可以忽略不计。 @Gordon ***.com/questions/239136/… c2.com/cgi/wiki?PrematureOptimization @Gordon,我们很难找到不引用 c2.com/cgi/wiki?PrematureOptimization 的编码器。这就是为什么我们有***.com/questions/239136/… 来回应c2.com/cgi/wiki?PrematureOptimization。 【参考方案1】:

如果您在循环内创建函数,您将创建 300 个单独的匿名函数对象php 不会对此进行优化,因为也许这就是您想要的。这比在循环之前创建一次函数效率要很多

这是创建两个独立对象的证明:http://3v4l.org/f3cdE

【讨论】:

但是由于匿名函数是不可变的,难道说引擎应该已经为我们优化了吗? 为此,PHP 首先必须分析函数是否完全相同。不变性不是问题,sameness 才是。如果你在闭包中包含了一些外部变量,那就很难说了。无论哪种方式,PHP ,不管它是否应该。 PHP 几乎可以按照您的要求执行;这不是像 Haskell 那样高度抽象的语言。 PHP 要求您使用 use (&lt;vars&gt;) 声明声明应在闭包中引用的外部变量。解析器可以很容易地判断该函数没有这个选项,所以它们都是一样的。 @deceze,好的。但是,当然,它们会是一样的,不是吗。他们怎么可能不同?即使使用诸如 function()use($e)echo $e; 之类的外部变量, $e 在创建函数时已经绑定,如果 $e 是相同的值,则函数必须完全相同不是吗? 当然,我只是说您对 PHP 编译器的期望过高。我从来没有写过 PHP 代码并想 “哦,不要担心性能,因为 PHP 会将其优化为我的意思而不是我写的...” 因为 PHP 没有. :)

以上是关于PHP引擎是不是优化循环内的匿名函数?的主要内容,如果未能解决你的问题,请参考以下文章

闭包的使用

Scala中方法内的匿名函数

使用iife调用回调内的匿名函数吗?

php的闭包(Closure)也就是匿名函数。是PHP5.3引入的。

揭秘PHP匿名函数

PHP匿名函数和闭包