PHP 7 performance improvements (2/5): ints/floats are free in PHP 7

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. Second episode: Free ints/floats saving up to 50% CPU usage.

By Julien Pauli, on Nov 21, 2016

The following is the 2nd episode of our blog series on PHP 7 performance improvements, detailed by Julien Pauli, PHP Contributor and Release Manager.

Read episode 1: Packed arrays

Read episode 3: Encapsed strings optimization

Read episode 4: References mismatch

Read episode 5: Immutable arrays

In PHP 7, the way variables are allocated in memory changed dramatically. They went from being stored on the heap to stack memory pools. As a side effect, you may reuse variable containers for free: no memory allocated. That’s impossible to do in PHP 5, where each variable creation/assignment requires some memory allocation (which is bad for performance).

Let’s have a look at this snippet :

for ($i=0; $i<10000; $i++) {
	$$i = 'foo';
}

This code creates 10.000 variables, named $0 to $10000, with the ‘foo’ string as a value. Creating a variable container for the first time (as in our example) obviously eats some memory. But what happens if now we re-use those variables, to now store an integer?

/* ... follow ... */

for ($i=0; $i<10000; $i++) {
$$i = 42;
}

Here, we are simply reusing variables that have already been allocated. PHP 5 needs to re-allocate 10.000 variables containers in memory, but PHP 7 just reuses the ones previously allocated, and store the 42 integer, which doesn’t raise memory usage at all. This is because integers and floats are absolutely free to use in PHP 7: their size is already allocated for the variable container itself.

Let’s see that using Blackfire:

variable-integer

Here again: not accessing the memory for variable modification leads to many CPU cycles, which are avoided in the second for loop in PHP 7. Thus the CPU usage dropped by 50% between PHP 5 and PHP 7. Also, because we are assigning an integer, the memory footprint is also much less in PHP 7 than in PHP 5. PHP 5 has to allocate 10.000 integers which weights 80.000 bytes (assuming we’re on an LP64 platform) plus a ton of overhead dedicated to the allocator management. That’s free in PHP 7.

If you can afford reusing already declared variables, especially if you are using many of them in a loop; do it in PHP 7!

Next week: Encapsed strings optimization.

Happy PHP 7’ing,

Julien Pauli

Julien is a web&system architect. He's been using PHP for more than a decade together with frameworks such as Symfony. He is now working at SensioLabs and is a PHP contributor and PHP 5.5/5.6 release manager. He tries to make PHP and its ecosystem better and more efficient.