PHP性能:将引用变量作为非引用参数传递

问题描述 投票:1回答:1
function M1($x, $y){}
function M2(&$x, $y){}
function M3(&$x, &$y){}

$arr = ['a' => ['b' => range(1, 1000)]];
$ref_arr = &$arr['a'];

$var = $ref_arr['b'];
$ref = &$ref_arr['b'];

//0.003000020980835 sec.
for($i = 0; $i < 10000; ++$i)
    M1($var, $var);

//0.59903407096863 sec.
for($i = 0; $i < 10000; ++$i)
    M2($var, $var);

//0.003000020980835 sec.
for($i = 0; $i < 10000; ++$i)
    M3($var, $var);

//1.1980690956116 sec.
for($i = 0; $i < 10000; ++$i)
    M1($ref, $ref);

//0.58603405952454 sec.
for($i = 0; $i < 10000; ++$i)
    M2($ref, $ref);

//0.003000020980835 sec.
for($i = 0; $i < 10000; ++$i)
    M3($ref, $ref);

据我所知,当将引用变量作为非引用参数传递时,PHP将复制该值。所以这条线需要最长的时间。

M1($ ref,$ ref); //1.1980690956116秒

但是如何解释这两条线的表现呢?

M2($ var,$ var); //0.59903407096863秒

M3($ var,$ var); //0.003000020980835秒

php performance pass-by-reference
1个回答
1
投票

几年后,没有人给我答案,所以我决定自己回答。

原因仍然是PHP中的COPY-ON-WRITE机制,但是当传递具有不同引用类型的参数时,复制在函数调用开始之前立即发生。

限定:

  • N表示非ref变量
  • R表示ref变量
  • - >用于参数传递

这3个表单不会触发参数复制:

  • N - > N.
  • R - > R.
  • N(ref count = 1) - > R.

对于这两种形式,总是会发生参数复制。

  • R - > N.
  • N(参考计数> 1) - > R.

因此,当您决定使用引用参数(通常是sortreset等数组函数)调用函数时,传递一个refcount大于1的数组并不是一个好主意。

不好的例子:

$arr1 = [];
$arr2 = $arr1;
sort($arr1);

好例子:

$arr1 = [];
$arr2 = $arr1;
unset($arr2);
sort($arr1);
© www.soinside.com 2019 - 2024. All rights reserved.