Using references in PHP?

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 "\n The results on my machine, Macbook 2.4GHz running PHP 5.3.2 function call with pass by reference: 2.14 sec function call with pass by value: 2.26 sec no function call, just bare increment: 0.42 sec 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: They make functions have side-effects. You should, in general, avoid functions with side-effects, as they make the program more unpredictable (as in "OK, how this did this value get here? Did any of the functions modify its parameters?

") They cause bugs. If you make a variable a reference, you must remember to unset it before assigning it a value, unless you want to change the underlying value of the reference set. This happens frequently after you run a foreach loop by reference and then re-use the loop variable.

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 Function call with pass by reference: 2.14 sec.

Function call with pass by value: 2.26 sec. No function call, just bare increment: 0.42 sec.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: They make functions have side-effects.

You should, in general, avoid functions with side-effects, as they make the program more unpredictable (as in "OK, how this did this value get here? Did any of the functions modify its parameters? ") They cause bugs.

If you make a variable a reference, you must remember to unset it before assigning it a value, unless you want to change the underlying value of the reference set. This happens frequently after you run a foreach loop by reference and then re-use the loop variable.

Amdahl's Law. When passings by reference is the slowest part of your application... worry about it. Otherwise, as you correctly say, you're being pound foolish.

Chances are, if it's a PHP application, you'll have a database object that will be a lot slower than any pass by reference call you make. – jlindenbaum Jun 3 '10 at 6:22.

The best practice is not to write a function when an expression will do. $param++; is all you need.

11 I believe he simply gave an example, and he does not plan on using that exact function. – John Jun 3 '10 at 0:57 3 @John: that's the major difference between programmers and philosophers: programmers solve specific tasks. Without clarification it is the best answer for the asked question.

– zerkms Jun 3 '10 at 1:00 1 @zerkms The OP explicitly said he's using it as an example: I am using simple incrementation to try to get what im askin across – deceze Jun 3 '10 at 1:32 1 @zerkms The questions wording could be drastically improved, but I think it's nonetheless clear that the focus of the question is the ($param) vs (&$param) part and that $param++ is just a placeholder, which could just as well be /* do something */. – deceze Jun 3 '10 at 1:47 1 @deceze: and the answer should rely on task, not on any best practice. Programmer should select the most appropriate implementation based on "&" nature and the base task: if function should return int - then it should be passed by value, if function should change data by reference - then it should be passed by reference.No any hidden reason or panacea.

– zerkms Jun 3 '10 at 1:54.

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).

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).

Jebus, it's justin frankel! – nickf Jun 3 '10 at 3:59.

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.

PHP's default is pass by value. So any interaction on a value passed into the function stays within that scope. – jlindenbaum Jun 3 '10 at 0:37 I thought PHP5 changed that?

– Graphain Jun 3 '10 at 0:39 IIRC PHP5's default is pass by value on everything except objects, which are pass by reference. – jlindenbaum Jun 3 '10 at 0:49 @jlindenbaum no, objects are passed by value. Well, actually, what's passed by value are the object references (or in this case you could call them "smart pointers"; they're not references in the sense of the rest of this discussion), the object is never passed around, so it seems to be passed by reference, but it's actual pass-object-reference-by-value.

– Artefacto Jun 3 '10 at 0:58 OP's first example specified to pass $param by reference, by the way. – BoltClock? Jun 3 '10 at 2:32.

I just ran a couple quick tests with the following code: This returned, consistently around .42 to .43, where as the following code returned about .55 to .59 So I would say that the references are quicker, but only in extreme cases.

1 Nice test but in PHP5 at least you should pretty much never use pointers for performance reasons. – Graphain Jun 3 '10 at 0:37 This test was run in PHP 5.3.1, but I may be wrong? – John Jun 3 '10 at 0:38 You should use microtime(true) to return the time as a float instead of a string.

Arithmetic on the string value is unreliable. – Bill Karwin Jun 3 '10 at 0:51 Ah, good point. Just re-ran the test with microtime(true) and 1,000,000 tests instead of 100,000.

The reference gets 4.9 - 5.1, while the returning function gets 5.5 - 5.7 – John Jun 3 '10 at 1:07 your function doesn't do anything. It should be return ++$param; – nickf Jun 3 '10 at 3:57.

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).

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).

Except... PHP uses copy-on-write – Artefacto Jun 3 '10 at 1:16.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions