I have an array of size 5 MB, I am passing it to functions to functions (I am not passing it by reference)
foo( $arr );
function foo( $arr ) {
....
bar( $arr );
....
}
function bar( $arr ) {
....
test( $arr );
....
}
function test( $arr ) {
....
test2( $arr );
....
}
PHP passes array values by value (copy of value) by default to functions.
my question is, if this array value is passed to 100 functions calls, will the PHP consumes 100 x 5 MB = 500 MB of memory ?
How the PHP handles big arrays ( in memory wise ) on function calls?
Here is a code to test:
<?php
function testnochanges($arr1){
foreach($arr1 as $val){
//
}
return $arr1;
}
function testwithchanges($arr1){
$arr1[] = 1;
return $arr1;
}
echo "Stage 0: Mem usage is: " . memory_get_usage() . "<br />";
for ($i = 0; $i < 100000; ++$i) {
$arr[] = rand();
}
echo "Stage 1 (Array Created): Mem usage is: " . memory_get_usage() . "<br />";
$arrtest1 = testnochanges($arr);
echo "Stage 2 (Function did NO changes to array): Mem usage is: " . memory_get_usage() . "<br />";
$arrtest2 = testwithchanges($arr);
echo "Stage 3 (Function DID changes to array): Mem usage is: " . memory_get_usage() . "<br />";
?>
and here is a output after i run it:
Stage 0: Mem usage is: 330656
Stage 1 (Array Created): Mem usage is: 8855296
Stage 2 (Function did NO changes to array): Mem usage is: 8855352
Stage 3 (Function DID changes to array): Mem usage is: 14179864
On stage 0 we can see that before array is created PHP is already using some space in memory. After creating first array (Stage 1) we can see a big change in memory usage as expected. But after calling function testnochanges
function and creating $arrtest1
on Stage 2, we see that memory usage did not change a lot. It's because we did no changes to $arr
, so $arrtest1
and $arr
still are pointing to the same array. But on Stage 3, where we call testwithchanges
function, and add an element to $arr
PHP performs copy-on-write
and returned array which is assigned to $arrtest2
now uses different part of memory and again we see a big grow of memory usage.
Dry conclusion: If you copy array to another array and do not change it, memory usage stays the same as both arrays are pointed to the same one. If you change the array PHP performs copy-on-write
and, of course memory usage grows.
Good thing to read: Be wary of garbage collection, part 2.
The only way to really find out how your particular use case performs is to complete a benchmark (quick and dirty is fine). If you are having trouble with performance, you may want to look into SPL. For example, SplFixedArray
can save memory when dealing larger arrays, granted you know the size beforehand. Also, newer versions of PHP handle garbage collection much better than previous versions, so upgrading may also help.
If you decide to run benchmarks, this will get you started (compares SPL with raw arrays): https://github.com/elazar/spl-benchmarks
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