49

Are there any issues, with regards to efficiency, for using a function call in a foreach loop. For example:

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

versus

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

Essentially, is php clever enough to call $this->getValues() only once in the first example, or does it call it on each iteration. If it calls it on each iteration, then how does it keep track of which element its currently at,

4
  • Well, the only downside with the second approach is that you require an extra variable (which takes up memory). So I would go with the first approach. Commented Jun 17, 2012 at 19:27
  • 1
    piers, the "extra variable" is not really there. PHP uses copy-on-write which means that $values and the foreach loop will reference the same dataset. The only thing to consider is when the variable can be garbage collected, which is earlier in the first example (at the end of the loop) than in the second (at the end of the function/file or when unset() is called). Commented Jun 17, 2012 at 19:32
  • 1
    @rambo coder - If you look at the example, you will see, that the function call is not really inside the loop. Commented Jun 17, 2012 at 19:37
  • 1
    @goat, the function call is not "inside" the loop. Commented Jul 4, 2015 at 11:24

2 Answers 2

51

These are both essentially the same:

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

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

$this->getValues() will only run once, as it is not inside the loop itself. If you need to use the return value of getValues again later, go ahead and assign it to a variable so you don't have to call the function again. If not, you don't really need a variable.

Sign up to request clarification or add additional context in comments.

2 Comments

So, categorically, $this->getValues() gets called once, and only once?
That's correct, but I'm not sure what you mean by "categorically". Why don't you test it? Have getValues log a message or output something directly with echo before returning the array so you can see how many times it's called.
27

There may be a difference, but it is going to be negligible for 99.9% of real-world cases. In either case, PHP will call your function/method only once. What happens internally when you use foreach is that PHP evaluates the iteratee (the part before the as) once, stores the result, and then loops over it, putting the current element into the local variable given after the as. If you write the iteratee to a local variable yourself, you are practically just duplicating PHP's effort, so the first approach may carry an extra overhead, but it's not going to be enough to worry about. I'd optimize for readability instead: if the function call is short and self-describing, inline it; if it's complex or obscure, store it in a descriptive variable instead.

Note that the situation is different with typical for and while loops, which is probably where you got this notion from. For example, in the following code:

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

...the getNumberOfItems() method gets called on every iteration. In this situation, it makes sense to precalculate it and store it in a local variable.

1 Comment

When you say so the first approach may carry an extra overhead I think you mean the second approach

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.