45

foreach ループで関数呼び出しを使用する場合、効率に関して問題はありますか。例えば:

foreach ($this->getValues() as $value) {
  //Do something with $value
}

$values = $this->getValues();
foreach ($values as $value) {
  //Do something with $value
}

基本的に、php は最初の例で $this->getValues() を 1 回だけ呼び出すほど賢いのでしょうか、それとも反復ごとに呼び出すのでしょうか。各反復でそれを呼び出す場合、現在どの要素にあるかをどのように追跡しますか?

4

2 に答える 2

47

これらは本質的に同じです:

foreach ($this->getValues() as $value) {
 //
}

$values = $this->getValues();
foreach ($values as $value) {
  //
}

$this->getValues()ループ自体の内部ではないため、一度だけ実行されます。の戻り値を後で再度使用する必要がある場合はgetValues、先に進んで変数に割り当てて、関数を再度呼び出す必要がないようにします。そうでない場合、変数は本当に必要ありません。

于 2012-06-17T19:28:03.917 に答える
23

違いはあるかもしれませんが、実際のケースの 99.9% では無視できる程度です。どちらの場合でも、PHP は関数/メソッドを 1 回だけ呼び出します。を使用すると内部的に何が起こるかとforeachいうと、PHP は iteratee ( の前の部分as) を 1 回評価し、結果を格納してからループし、現在の要素を . の後に指定されたローカル変数に入れますas。iteratee を自分でローカル変数に書き込むと、実際には PHP の作業が重複するだけなので、最初の方法では余分なオーバーヘッドが発生する可能性がありますが、心配するほどではありません。代わりに、読みやすさを最適化します。関数呼び出しが短く自己記述的である場合は、インライン化します。複雑またはあいまいな場合は、代わりに記述変数に保存してください。

通常のループforwhileループでは状況が異なることに注意してください。これは、おそらくこの概念から得たものです。たとえば、次のコードでは:

for ($number = 0; $number < $this->getNumberOfItems(); ++$number) {
    // do stuff...
}

...getNumberOfItems()メソッドは反復ごとに呼び出されます。この状況では、それを事前に計算してローカル変数に格納するのが理にかなっています。

于 2012-06-17T19:34:50.947 に答える