Bruno Guignard
Bruno Guignard

Reputation: 303

Is it really usefull for performance to pass values by reference in foreach in PHP 7

Since PHP7.0, foreach loops have been modified and a new behavior has been set to make reference quicker than before (foreach $tab as &$val).

But I've read many times that passing by reference is actually sometimes slower than a the common loop (foreach $tab as $val)

Is it always quicker ? Always slower ? Does it depend on what we are doing in the foreach loop ? Since references in PHP are not references it's confusing... I'm a bit sick of reading different answers about this subject across the web and I cant figure out where the truth is.

Thank you for bringing some light here ;)

Source : https://blog.eduonix.com/web-programming-tutorials/learn-changes-foreach-statement-php-7/ Source : http://php.net/manual/fr/control-structures.foreach.php Source : http://php.net/manual/en/language.references.arent.php ...

Upvotes: 2

Views: 776

Answers (2)

Rick James
Rick James

Reputation: 142258

Executive Summary: You are worrying about a performance problem that does not exist.

Details

PHP uses "COW" (Copy On Write).

Normal passing ($val):

  • Scalar -- pass the value. Writing to it changes only the local copy.
  • Structure/array/etc -- pass pointer to it. If the receiver (foreach loop or function body) wants to change any part of the structure, the structure is copied. The cost is proportional to the size of the structure.

Pass by reference (&$val):

  • Scalar -- pass a pointer to the scalar so that the innards can actually change it.
  • Structure -- pass the pointer. If the receiver writes to the structure, it simply (efficiently) goes through the pointer to get to the item in the structure. No COW.

The wisdom in the design is that 99% of the time PHP "just works", and is efficient, and the user does not need to know that there are two passing techniques. The tricky part is that you need to understand when to do the &$val thing.

PHP is different than virtually all other languages.

  • ALGOL 60 -- Pass by value or "name" (sort of like anonymous functions in newish languages)
  • FORTRAN -- Only pass by "reference" (pointer). A drawback is that if you pass a literal, the receiver can change the value of the literal! (OK, that was a 'bug' baked into old compilers.)
  • C -- Only pass by value. But you could say (with syntax) that you want the pointer to the thing and then dereference on the inside.
  • Pascal -- Value or Reference, but not identical to anything above (I forget the details).

It seems there are almost as many ways to "pass arguments" as there are Languages.

Back to the Question:

  • If you are passing a scalar, there may be a tiny performance penalty by having &$val, and going through the pointer.
  • If you are passing a structure and don't need to write to it, there is probably zero difference.
  • If you are passing a structure and do need to write to it, then you should have decided on how to pass it based on whether you want the change to be preserved, not on performance.

Upvotes: 4

Mike Robinson
Mike Robinson

Reputation: 8945

The language designers are simply trying to handle the situation where the array elements are big, and to clarify directly in the source-code exactly what is to occur. You can now tell PHP that the variable, $val, is to contain a reference to the array-element, which means that the big-value won't be duplicated and the memory garbage-collector won't have more work to do, and the source-code clearly says so. Subsequent programmers who read this statement will know exactly what PHP is going to do.

Of course, references are naturally more-efficient than copying values around in memory.

Upvotes: 0

Related Questions