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

时间:2017-11-18 07:28:29

标签: php performance pass-by-reference

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秒。

1 个答案:

答案 0 :(得分:1)

经过数年的努力,没有人给我答案,所以我决定自己回答。

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

定义:

  • N用于非引用变量
  • R代表参考变量
  • ->用于参数传递

这3种形式不会触发参数复制:

  • N-> N
  • R-> R
  • N(引用计数= 1)-> R

对于这2种形式,总是会出现参数复制。

  • R-> N
  • N(引用计数> 1)-> R

因此,当您决定调用带有引用参数的函数(通常是数组函数,例如functionsort)时,传递引用计数大于1的数组不是一个好主意。

错误的例子:

reset

很好的例子:

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