PHP如何使用ref或value传递的参数?

时间:2016-08-02 09:44:53

标签: php arrays reference parameter-passing

我做了一个小实验,我得到了一个令人惊讶的结果(至少对我而言)。我已经编写了6个函数来以不同的方式在PHP中总结一个数组。在这里你可以看到结果:

PHP ver: 5.5.36
foreach_by_value():     1.1668000221252
foreach_by_ref():       0.38018989562988
array_sum_by_value():   0.11428999900818
array_sum_by_ref():     0.91070008277893
for_by_value():         0.50360298156738
for_by_ref():           1.2752962112427

正如您所看到的,通过引用传递数组有时会使其在较慢的其他情况下更快。 我真的不知道这背后的原因是什么。

以下是我用于测试的代码:

echo phpversion() . "\n";

const N = 100000;
const REPEAT = 100;

for ($i = 0;$i < N;$i++) {
    $array[] = rand(0, 10000);
}

function foreach_by_value($a) {
    $sum = 0;
    foreach($a as $number) {
        $sum += $number;
    }
}

function foreach_by_ref(&$a) {
    $sum = 0;
    foreach($a as $number) {
        $sum += $number;
    }
}

function array_sum_by_value($a) {
    $sum = array_sum($a);
}

function array_sum_by_ref(&$a) {
    $sum = array_sum($a);
}

function for_by_value($array) {
    $sum = 0;
    $count = count($array);
    for($i = 0;$i < $count;$i++) {
        $sum += $array[$i];
    }
}

function for_by_ref(&$array) {
    $sum = 0;
    $count = count($array);
    for($i = 0;$i < $count;$i++) {
        $sum += $array[$i];
    }
}


$start_time = microtime(true);
for ($i = 0;$i < REPEAT;$i++) {
    foreach_by_value($array);
}
$finish_time = microtime(true);
echo "foreach_by_value(): \t" . ($finish_time - $start_time) . "\n";

$start_time = microtime(true);
for ($i = 0;$i < REPEAT;$i++) {
    foreach_by_ref($array);
}
$finish_time = microtime(true);
echo "foreach_by_ref(): \t" . ($finish_time - $start_time) . "\n";


$start_time = microtime(true);
for ($i = 0;$i < REPEAT;$i++) {
    array_sum_by_value($array);
}
$finish_time = microtime(true);
echo "array_sum_by_value(): \t" . ($finish_time - $start_time) . "\n";

$start_time = microtime(true);
for ($i = 0;$i < REPEAT;$i++) {
    array_sum_by_ref($array);
}
$finish_time = microtime(true);
echo "array_sum_by_ref(): \t" . ($finish_time - $start_time) . "\n";

$start_time = microtime(true);
for ($i = 0;$i < REPEAT;$i++) {
    for_by_value($array);
}
$finish_time = microtime(true);
echo "for_by_value(): \t" . ($finish_time - $start_time) . "\n";

$start_time = microtime(true);
for ($i = 0;$i < REPEAT;$i++) {
    for_by_ref($array);
}
$finish_time = microtime(true);
echo "for_by_ref(): \t\t" . ($finish_time - $start_time) . "\n";

1 个答案:

答案 0 :(得分:2)

  • foreach_by_value - 循环枚举数组并复制当前数据 值为临时变量$number,因此需要额外的时间;
  • foreach_by_ref - 循环枚举数组但不复制 任何东西,只需加上总和;
  • array_sum_by_value - 内部函数 (用C ++编写)枚举数组并计算总和,所以这个 是最快的结果;
  • array_sum_by_ref - 内部函数(用C ++编写)枚举数组,但由于每次对next()的内部调用都是引用,这需要额外的时间进行重定向(对于每个元素,数组);
  • for_by_value - 它不使用任何临时变量,但由于它使用索引而不是current()next(),这比 foreach_by_ref需要更多时间
  • for_by_ref - 由于函数的参数是通过引用传递的,因此对参数的每次访问都有一个重定向,这需要时间;