2013-08-05 16 views
5

私は、単一のanonymous functionに複数の参照を格納する配列があります。PHPエンジンはループ内で匿名関数を最適化しますか?

$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.. 
    }; 
} 

エンジンは、1つのオブジェクトのみを作成する必要があることを認識するほどスマートですか?

上記のコードは1つのオブジェクトのみを作成するか、1つのオブジェクトを作成しますか反復ごとに

(質問はHHVMおよびZend Engineの両方を対象としています。)

+0

あなたはそれをプロファイルしましたか? 300オブジェクトは何もありません。あなたはその少数のオブジェクトとの違いを測定することさえできないでしょう。数百万のオブジェクトを作成しない限り、その差はごくわずかです。 – Gordon

+0

@Gordon http://stackoverflow.com/questions/239136/fastest-way-to-convert-string-to-integer-in-php#comment-4932053 – Pacerier

+0

http://c2.com/cgi/wiki?PrematureOptimization – Gordon

答えて

5

あなたがループ内で関数を作成する場合は、300個々の匿名関数を作成していることオブジェクト。おそらくそれがあなたが望むものなので、PHPはこれを最適化しません。それは であり、多くの場合、ループの前に関数を作成するよりも効率的ではありません。

ここでは、2つの独立したオブジェクトが作成されますことを証明です:http://3v4l.org/f3cdE

+0

しかし、匿名関数は不変なので、エンジン*が私たちのためにこれを最適化していたはずであると言うのは本当ですか? – Pacerier

+2

そのためには、まず関数が正確に*同じ*かどうかをPHPが分析しなければなりません。不変性は問題ではない、*同一性*は問題ではない。クロージャーにいくつかの外部変数を含めると、それは伝えるのが難しくなります。そしてどちらにしても、PHP *は、それが*必要であるかどうかにかかわらず、*ではありません。 PHPは、あなたがそれを伝えるものをほとんど行いません。これはHaskellのような非常に抽象的な言語ではありません。 – deceze

+4

PHPでは、 'use()'宣言でクロージャーで参照されるべき外部変数を宣言する必要があります。パーサーは、この関数がこのオプションを持たないことを簡単に知ることができるので、それらの関数はすべて同じです。 – Barmar