PHP数组性能-内存方面



我有一个大小为5 MB的数组,我将它传递给函数到函数(我不是通过引用传递)

foo( $arr );
function foo( $arr ) {
....
bar( $arr );
....
}
function bar( $arr ) {
....
test( $arr );
....
}
function test( $arr ) {
....
test2( $arr );
....
}

PHP默认情况下通过值(值的副本)将数组值传递给函数。

我的问题是,如果这个数组值被传递给100个函数调用,PHP会消耗100 x 5 MB=500 MB的内存吗?

PHP如何处理函数调用中的大数组(内存方面)?

这里有一个要测试的代码:

<?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 />";

?>

这是我运行后的输出:

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

阶段0中,我们可以看到在创建数组之前,PHP已经在使用内存中的一些空间。在创建第一个数组(Stage 1)之后,我们可以看到内存使用率如预期的那样发生了巨大变化。但是,在Stage2上调用函数testnochanges函数并创建$arrtest1之后,我们发现内存使用情况没有太大变化。这是因为我们没有更改$arr,所以$arrtest1$arr仍然指向同一个数组。但是在阶段3,我们调用testwithchanges函数,并向$arr添加一个元素。PHP执行copy-on-write,返回的分配给$arrtest2的数组现在使用不同的内存部分,我们再次看到内存使用量的大幅增长。

枯燥的结论:如果将数组复制到另一个数组而不更改它,则内存使用率将保持不变,因为两个数组都指向同一个数组。如果您更改数组,PHP将执行copy-on-write,当然内存使用量也会增加。

值得一读的是:警惕垃圾收集,第2部分。

真正了解特定用例执行情况的唯一方法是完成一个基准测试(快速而肮脏也没关系)。如果您在性能方面遇到问题,您可能需要了解SPL。例如,SplFixedArray在处理较大的数组时可以节省内存,前提是您事先知道大小。此外,较新版本的PHP比以前的版本更好地处理垃圾收集,因此升级也可能有所帮助。

如果您决定运行基准测试,这将使您开始(将SPL与原始阵列进行比较):https://github.com/elazar/spl-benchmarks

最新更新