Optimized by-value Assignments in PHP

In programming some variable types are passed by value, others by reference. Using one or the other has a number of implications. This article handles about the implications of passing variables by value on speed and memory usage in PHP.

According to the Zend PHP5 certification study guide, by-reference activity is often slower than using the same by-value activity. The cause would be a mechanism to optimize by-value assignments called “deferred-copy”.

In most programming languages arrays are passed by reference. In PHP on the other hand, arrays are passed by value. Since arrays are often used for storing lots of values, we’ll be using them in some tests.

Functions

What happens when you pass a large array to a function?

The test code :

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo($bar) {
    echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;
    echo $bar[0] . PHP_EOL;
    echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;
    $bar[0] = 'barfoo';
    echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;
}
 
$array = array_fill(0, 100000, 'foobar');
echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;
 
foo($array);
echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;

This code outputs :

1
2
3
4
5
Memory usage : 5389232 bytes
foobar
Memory usage : 5389232 bytes
Memory usage : 10713648 bytes
Memory usage : 5388680 bytes

Which shows that the function parameter isn’t copied until it’s value changes. This is the deferred-copy mechanism at work.

Variables

The same effect occurs with simply copying variables :

1
2
3
4
5
6
$array1 = array_fill(0, 10000, 'foobar');
echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;
$array2 = $array1;
echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;
$array1[0] = 'barfoo';
echo 'Memory usage : ' . memory_get_usage() . ' bytes '. PHP_EOL;

This code shows that the array is copied for real when one of the 2 copies is changed. The code outputs :

1
2
3
Memory usage : 610960 bytes 
Memory usage : 611040 bytes 
Memory usage : 1156704 bytes

Conclusion

Thanks to deferred-copy, you don’t have to be afraid for performance issues when passing large variables by value in PHP. Only when you change the variable, the variable is copied for real.

Leave a Reply

Your email address will not be published. Required fields are marked *