Reputation: 18798
I ask this question because i learned that in programming and designing, you must have a good reason for decisions. I am php learner and i am at a crossroad here, i am using simple incrementation to try to get what im asking across. I am certainly not here to start a debate about the pros/cons of referencing, but when it comes to php, which is the better programming practice:
function increment(&$param) {
++$param;
}
vs.
function increment($param){
return ++$param;
}
$param = increment($param);
Upvotes: 4
Views: 1401
Reputation: 2264
I just ran a couple quick tests with the following code:
<?php
function increment(&$param){
$param++;
}
$param = 1;
$start = microtime();
for($i = 1; $i <= 1000000; $i++) {
increment($param);
}
$end = microtime();
echo $end - $start;
?>
This returned, consistently around .42 to .43, where as the following code returned about .55 to .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;
?>
So I would say that the references are quicker, but only in extreme cases.
Upvotes: 1
Reputation: 522016
It depends on what the functions purpose is. If its express purpose is to modify the input, use references. If the purpose is to compute some data based on the input and not to alter the input, by all means use a regular return
.
Take for example array_push
:
int array_push(array &$array, mixed $var[, mixed $...])
The express purpose of this function is to modify an array. It's unlikely that you need both the original array and a copy of it including the pushed values.
array_push($array, 42); // most likely use case
// if you really need both versions, just do:
$old = $array;
array_push($array, 42);
If array_push
didn't take references, you'd need to do this:
// array_push($array, $var[, $...])
$array = array_push($array, 42); // quite a waste to do this every time
On the other hand, a purely computational function like pow
should not modify the original value:
number pow(number $base, number $exp)
You are probably more likely to use this function in a context where you want to keep the original number intact and just compute a result based on it. In this case it would be a nuisance if pow
modified the original number.
$x = 123;
$y = pow($x, 42); // most likely use case
If pow
took references, you'd need to do this:
// pow(&$base, $exp)
$x = 123;
$y = $x; // nuisance
pow($y, 42);
Upvotes: 3
Reputation: 562260
First, references are not pointers.
I tried the code given by @John in his answer, but I got strange results. It turns out microtime()
returns a string. Arithmetic is unreliable and I even got negative results on some runs. One should use microtime(true)
to get the value as a float.
I added another test of no function call, just incrementing the variable:
<?php
$param = 1;
$start = microtime(true);
for($i = 1; $i <= 1000000; $i++) {
$param++;
}
$end = microtime(true);
echo "increment: " . ($end - $start) . "\n";
The results on my machine, Macbook 2.4GHz running PHP 5.3.2.
So there seems to be a 5.3% performance advantage to passing by reference, but there is a 81% performance advantage to avoiding the function call completely.
I guess the example of incrementing an integer is arbitrary, and the OP is really asking about the general advantage of passing by reference. But I'm just offering this example to demonstrate that the function call alone incurs far more overhead than the method of passing parameters.
So if you're trying to decide how to micro-optimize parameter passing, you're being penny wise and pound foolish.
There are also other reasons why you should avoid references. Though they can simplify several algorithms, especially when you are manipulating two or more data structures that must have the same underlying data:
Upvotes: 10
Reputation: 117
The second version:
function increment($param){
return $param++;
}
$param = increment($param);
Does nothing. increment() returns $param. Perhaps you meant ++$param or $param+1;
I mention this not to be pedantic, but so that if you compare timings, you are comparing the same function (it could be possible for PHP's optimizer to remove the function completely).
Upvotes: 2
Reputation: 1881
I'd say it would quite depend on what you're doing. If you're trying to interact on a large set of data without wanting an extra copy of it in memory - go ahead, pass by value (your second example). If you want to save the memory, and interact on an object directly - pass by reference (your first example)
Upvotes: 0
Reputation: 1245
The best practice is not to write a function when an expression will do.
$param++;
is all you need.
Upvotes: 2
Reputation: 41823
I think your example is a little abstract.
There is no problem with using pointers but in most real-world cases you are probably modifying an object not an int in which case you don't need the reference (in PHP5 at least).
Upvotes: 0
Reputation: 723448
By definition, incrementing a variable's value (at least in PHP) mutates the variable. It doesn't take a value, increase it by 1 and return it; rather it changes the variable holding that value.
So your first example would be the better way to go, as it's taking a reference (PHP doesn't really do pointers per se) of $param
and post-incrementing it.
Upvotes: 1