Reputation: 2675
It has been explained quite thoroughly that you only pass by reference in PHP if their is a technical reason to do so, because Copy-On-Write basically makes the performance equivalent. From what I understand, if it is never changed it never does copy the object.
But what if the function does change the variable, but your code never uses it again/does not use any part that is changed? it does not matter to the code if the original is changed or not. Yes, it is possible that the PHP optimiser takes this situation into account, but I have no reason to believe it does.
And passing a single reference is sure going to be a whole lot faster than copying a huge array or object.
So is this is good situation to pass by reference or not?
For Example, say you pass in a DomCrawler (not much more than a big [html formatted] string, except it is passed by reference implicitly in this specific case). Crawl a little and extract some information. In many situations you would not need that Crawler reset to its original position, as you are simply not using it again. Also, imagine latter that we do use the DOMCrawler, we read the URI from it. The function did not change this, so passing by reference or value is still equivalent, but will passing by reference not be significantly more optimal? I think this situation would be very hard for any optimiser to spot.
Upvotes: 1
Views: 2427
Reputation: 541
I've always avoided passing by reference for the same reason I avoid goto.
$a = myFunction($a);
Is more easily read and reused than myFunction(&$a);
Upvotes: 1
Reputation: 50021
So is this is good situation to pass by reference or not?
No.
Okay. Imagine you have a $bigString and you pass it to a function, the function modifies it and does something with it and the caller never wants it again. Passing by reference is initially faster since it avoids the copy. However, it's still a bad idea.
(1) If a different caller calls your function that does want to continue using that variable, things break. The reference violates encapsulation, basically.
(2) As soon as you have more than 1 non-reference variable outside the function refering to that value, merely creating the reference requires the copy again. (Variable values are held in containers that may be either a non-reference (copy-on-modify) or a reference (do nothing special on modify), so for reference variables and non-reference variables to try refer to that value at the same time, it has to be duplicated.)
(3) Because of the above, something as innocent as calling strlen within the function will have to duplicate the value, because strlen's parameter is passed by-value, which is the norm. Now imagine you call a few functions, such as substr, and maybe strlen in a loop, and you're making a new copy of the data every time.
(4) DDR3 RAM can shove around more than 10 GB per second and CPU cache RAM is goodness knows how fast. I think there are bigger things to worry about with PHP performance than how long a string or array copy takes.
Don't use references for superstitious performance gains. It never works.
If you really want to avoid the copy, the right way to do this is probably to put your function as a method of an object that looks after the variable:
class Thing {
private $bigString;
public function foo() {
$this->bigString[0] = 'x';
}
}
Then you avoid copying, get the benefits of encapsulation and none of the subtleties of references.
PS: DomCrawler is not a good example because it's an object. PHP objects are never copy-on-write anyway (well I think they are, but there is an additional level of indirection so the only part that is copy-on-write is a small pointer container, or something like that).
Upvotes: 4
Reputation: 3593
From my understanding of the PHP system, everything is passed by "reference". So if you are passing around huge arrays or objects, they are always passed by "reference".
I put "reference" in quotes cause there are 2 different types here:
PHP defaults to the implicit reference.
So there is no performance implications until such a time as you change an implicit reference. In this case PHP will allocate copy the values to separate memory addresses and update your reference.
If the compiler detects that the variable is no longer used or is no longer in scope, the GC will scoop it up.
Upvotes: 0