OK, so it's time for some PHP Mythbusters! Please start by reading the PHP documentation on how garbage collection works, as I'm going to assume some prior knowledge of how this all works:
The second document specifically explains what triggers the running of the cyclic garbage collector. It has nothing to do with "free CPU cycles" or "low memory" — it's based entirely on the number of potential garbage objects that are present:
When the garbage collector is turned on, the cycle-finding algorithm as described above is executed whenever the root buffer runs full. The root buffer has a fixed size of 10,000 possible roots.
That is, the cyclic garbage collector runs any time that a certain number of potentially garbage objects have accumulated, irrespective of the size of those objects. Reviewing the code in zend_gc.c
confirms this — there is certainly nothing in there checking the overall amount of free memory, and there's certainly none of the threading that would be needed to make the GC run while the CPU is free. So I think we can call this part "busted".
Next, let's take a look at what the actual difference between $x = null
and unset($x)
might be. First, let's confirm that they do the same thing using this class as our Buster the Test Dummy:
class NoisyDestructor {
function __destruct() {
print "Destructor called\n";
}
}
Now, let's see what the difference between setting a variable to null and unset()
-ing it is:
$x = new NoisyDestructor();
print "Created\n";
$x = null;
print "Nulled\n";
print "\n";
$x = new NoisyDestructor();
print "Created\n";
unset($x);
print "Unset\n";
When we run this, we see:
Created
Destructor called
Nulled
Created
Destructor called
Unset
Wait a minute — that's the exact same sequence for both! There's no functional difference between the two. Now, how about the performance?
class Thing { }
$start = microtime(true);
for ($i = 0; $i < 1e6; $i++) {
$x = new Thing();
$x = null;
}
printf("%f sec for null\n", microtime(true) - $start);
$start = microtime(true);
for ($i = 0; $i < 1e6; $i++) {
$x = new Thing();
unset($x);
}
printf("%f sec for unset\n", microtime(true) - $start);
Now, using my laptop to test, with PHP 5.4, I get:
0.130396 sec for null
0.175086 sec for unset
Not only is the performance difference between setting a variable to null and unsetting it pretty minor, considering how many times we had to run this loop to see this result, but it's actually the exact opposite of what that comment claimed: unset()
is about 25% slower! This PHP myth has been well and truly busted.
TL;DR: The quote you found is completely wrong. (It seems likely that it was removed from PHP.net for this exact reason.)