PHP 7 performance improvements (4/5): References mismatch

PHP 7 performance improvements (4/5): References mismatch

Julien Pauli, PHP contributor and release manager, details what changed between PHP 5 and PHP 7, and how to migrate and make effective use of the language optimizations. All statements are documented with specific examples and Blackfire profiles. Fourth episode: References mismatch generating no overhead.

The following is the 4th episode of our blog series on PHP 7 performance improvements, detailed by Julien Pauli PHP Contributor and Release Manager. We will update this introduction with links to all other articles when they are published.
Read episode 1: Packed arrays
Read episode 2: ints/floats are free in PHP 7
Read episode 3: Encapsed strings optimization

Reference mismatch happens when you pass a non-ref variable to a function argument passed-by-ref, or the opposite. Something like this:

function foo(&$arg) { } $var = 'str'; foo($var);

Do you know what horrible things happen under the hood in the PHP 5 engine? In PHP 5, whenever there is a reference mismatch, the engine is forced to duplicate the variable before passing it as an argument to a function. As you probably guessed, if the variable contains something big, like a several-thousands-entries array or a big chunk of string; the copy will take a lot of time.

This is because of the way variables and references used to work into PHP 5. When going into the body function, the engine doesn’t know yet if you will change the argument value. If you are, then as the argument is taken by reference, the change must be reflected outside if a reference variable were passed. What if it was not the case (as in our example)? The engine must then create a reference, from the non-reference variable you passed it in the function call. This procedure leads the engine to fully duplicate the variable content in PHP 5 (calling a lot of memcpy() on very sparse pointers, leading to tons of slow memory accesses).

In PHP 7, when the engine wants to create a reference from a non-reference variable, it just wraps the latter into the newly created former, that’s all. There is no memory copy, anywhere. This is because variables work in a very different way internally in PHP 7, and references have been deeply reworked.

Look at this piece of code:


Originally published at laravelfeed.com.

Like what you read? Give LaravelFeed a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.