When calling functions and passing in a large string I normally pass by reference. The intent is to keep PHP from passing by value a copy of the string, thus reducing memory usage. However, I have noticed the opposite under certain circumstances.
In the below example, peak memory usage doubles when passing the string by reference into the function, at the is_string() call.
Code:
$buf = '';
report_memory(__LINE__);
$buf = file_get_contents('./20MB.pdf');
report_memory(__LINE__);
example($buf);
report_memory(__LINE__);
function example(& $str) {
report_memory(__LINE__);
is_string($str);
report_memory(__LINE__);
}
function report_memory($line=0) {
echo 'Line: ' . str_pad($line,3) . ' ';
echo 'Mem: ' . str_pad(intval(memory_get_usage()/1024 ) . 'K',8) . ' ';
echo 'Peak: ' . str_pad(intval(memory_get_peak_usage()/1024) . 'K',8) . ' ';
echo "\n";
}
Output:
Line: 2 Mem: 625K Peak: 631K
Line: 5 Mem: 21058K Peak: 21076K
Line: 11 Mem: 21058K Peak: 21076K
Line: 13 Mem: 21058K Peak: 41494K
Line: 8 Mem: 21058K Peak: 41494K
Changing the function example() to remove the reference:
function example($str) {
report_memory(__LINE__);
is_string($str);
report_memory(__LINE__);
}
Output:
Line: 2 Mem: 625K Peak: 631K
Line: 5 Mem: 21058K Peak: 21076K
Line: 11 Mem: 21058K Peak: 21076K
Line: 13 Mem: 21058K Peak: 21076K
Line: 8 Mem: 21058K Peak: 21076K
This is what I would expect. So then why the memory doubling with is_string() when the variable is a reference?
The environment is CentOS 6.6 running a stock PHP 5.3.3.
Zend Engine uses a lazy-copy mechanism. Until the variable is modified it does not create a copy of the variable. PHP create a set of structures that it uses to maintain the reference that why it is actually “slower” to pass a variable by reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With