我问这个问题,因为我了解到在编程和设计中,你必须有充分的理由做出决定。我是PHP学习者,我在这里的十字路口,我使用简单的增量试图得到我要求的东西。我肯定不会在这里开始讨论引用的优缺点,但是当涉及到php时,这是更好的编程实践:
function increment(&$param) {
++$param;
}
VS
function increment($param){
return ++$param;
}
$param = increment($param);
答案 0 :(得分:10)
首先,references are not pointers。
我尝试了@John在他的回答中给出的代码,但我得到了奇怪的结果。事实证明microtime()
返回一个字符串。算术是不可靠的,我甚至在某些运行中得到了负面结果。应该使用microtime(true)
将值作为浮点值。
我添加了另一个没有函数调用的测试,只是递增变量:
<?php
$param = 1;
$start = microtime(true);
for($i = 1; $i <= 1000000; $i++) {
$param++;
}
$end = microtime(true);
echo "increment: " . ($end - $start) . "\n";
我的机器上的结果,Macbook 2.4GHz运行PHP 5.3.2。
因此,通过引用传递似乎有5.3%的性能优势,但完全避免函数调用有81%的性能优势。
我想增加一个整数的例子是任意的,OP实际上是在询问通过引用传递的一般优势。但我只是提供这个例子来证明单独的函数调用会产生比传递参数的方法更多的开销。
因此,如果您正在尝试决定如何微观优化参数传递,那么您就是明智而且愚蠢。
还有其他原因可以避免引用。虽然它们可以简化几种算法,特别是当您操作两个或多个必须具有相同基础数据的数据结构时:
答案 1 :(得分:3)
这取决于功能目的是什么。如果其明确目的是修改输入,请使用引用。如果目的是根据输入计算一些数据,而不来改变输入,请务必使用常规return
。
int array_push(array &$array, mixed $var[, mixed $...])
此功能的明确目的是修改数组。你不太可能需要原始数组和它的副本,包括推送值。
array_push($array, 42); // most likely use case
// if you really need both versions, just do:
$old = $array;
array_push($array, 42);
如果array_push
没有参考,您需要这样做:
// array_push($array, $var[, $...])
$array = array_push($array, 42); // quite a waste to do this every time
另一方面,像pow
这样的纯计算函数不应该修改原始值:
number pow(number $base, number $exp)
您可能更有可能在要保持原始数字完整的上下文中使用此函数,并仅根据它计算结果。在这种情况下,如果pow
修改了原始数字,那将是一件麻烦事。
$x = 123;
$y = pow($x, 42); // most likely use case
如果pow
接受了引用,则需要执行此操作:
// pow(&$base, $exp)
$x = 123;
$y = $x; // nuisance
pow($y, 42);
答案 2 :(得分:2)
最佳做法是在表达式执行时不写函数。
$param++;
就是你所需要的一切。
答案 3 :(得分:2)
第二个版本:
function increment($param){
return $param++;
}
$param = increment($param);
什么都不做。 increment()返回$ param。也许你的意思是++ $ param或$ param + 1;
我提到这不是迂腐,但是如果你比较时间,那么你正在比较相同的函数(PHP的优化器可能完全删除该函数)。
答案 4 :(得分:1)
根据定义,递增变量的值(至少在PHP中)会改变变量。它不需要一个值,将它增加1并返回它;相反,它改变了持有该值的变量。
所以你的第一个例子是更好的方法,因为它正在引用$param
并且后期递增它的引用(PHP本身并不是指针)。
答案 5 :(得分:1)
我刚用以下代码进行了几次快速测试:
<?php
function increment(&$param){
$param++;
}
$param = 1;
$start = microtime();
for($i = 1; $i <= 1000000; $i++) {
increment($param);
}
$end = microtime();
echo $end - $start;
?>
此返回,始终在.42到.43之间,其中以下代码返回.55到.59
<?php
function increment($param){
return $param++;
}
$param = 1;
$start = microtime();
for($i = 1; $i <= 1000000; $i++) {
$param = increment($param);
}
$end = microtime();
echo $end - $start;
?>
所以我会说引用更快,但仅限于极端情况。
答案 6 :(得分:0)
我认为你的例子有点抽象。
使用指针没有问题但在大多数实际情况下你可能修改了一个对象而不是int,在这种情况下你不需要引用(至少在PHP5中)。
答案 7 :(得分:0)
我会说这完全取决于你在做什么。如果您尝试在大量数据上进行交互而不想在内存中添加额外的副本 - 请继续,按值传递(第二个示例)。如果你想保存内存,并直接在一个对象上进行交互 - 通过引用传递(你的第一个例子)