the difference between unset and = null

Php

Php Problem Overview


From a random php.net post:

> If you are doing $whatever = null; then you are rewriting variable's > data. You might get memory freed / shrunk faster, but it may steal CPU > cycles from the code that truly needs them sooner, resulting in a > longer overall execution time.

Apparently this is the undisputed truth so maybe someone would be so kind as to explain.

I mean, what, does unset magically not execute any assembly instructions whereas $whatever = null; does? The answer, as given, is about as useful as saying

>$whatever = null resets the buffer and the L1 cache whereas unset clears the buffer and resets the L2 cache.

Techno mumbo jumbo doesn't constitute an answer.

Php Solutions


Solution 1 - Php

An important difference between both methods is that unset($a) also removes $a from the symbol table; for example:

$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);

Outputs:

Notice: Undefined variable: a in xxx
NULL

But when $a = null is used:

$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);

Outputs:

NULL

I ran the code through a benchmark as well and found that $a = null is roughly 6% faster than its unset() counterpart. It seems that updating a symbol table entry is faster than removing it.

Addendum

The other difference (as seen in this small script) seems to be how much memory is restored after each call:

echo memory_get_usage(), PHP_EOL;
$a = str_repeat('hello world ', 100);
echo memory_get_usage(), PHP_EOL;
// EITHER unset($a); OR $a = null;
echo memory_get_usage(), PHP_EOL;

When using unset() all but 64 bytes of memory are given back, whereas $a = null; frees all but 272 bytes of memory. I don't have enough knowledge to know why there's a 208 bytes difference between both methods, but it's a difference nonetheless.

Solution 2 - Php

When using unset, memory usage and processing time is less.

http://php.net/manual/en/function.unset.php#105980

Solution 3 - Php

I made a simple test.

Considering a simple class like this:

class Cat{
    public $eyes  = 2;
    public $claws = 4;
    public $name  = "Kitty";
    public $sound = ['Meow', 'Miaou'];
}

I run this code code

$start = microtime(true);

for($i = 10000000; $i > 0; --$i){
    $cat = new Cat;
    $cat = null;
}

$end = microtime(true);

printf("Run in %s and use %s memory",
        round($end - $start, 2), round(memory_get_usage() / 1000, 2));

> Run in 1.95 and use 233.29 memory

And this

for($i = 10000000; $i > 0; --$i){
    $cat = new Cat;
    unset($cat);
}

> Run in 2.28 and use 233.1 memory

For what is worth it seem the null method run faster.

Solution 4 - Php

The answers above are great, especially the comment that "An important difference between both methods is that unset($a) also removes $a from the symbol table".

However, I don't think anyone has really fully answered the question in a practical sense because they don't describe how the two are used. OK I think we know that they both basically do the same thing. Why use one over the other?

null

Reclaims memory immediately (at the expense taking longer) despite PHP self managing memory /garbage collection.

unset()

Is usually recommended as it reclaims memory "when I can get to it" and is therefore considered faster as it doesn't dedicate resources immediately to it.

When should use null vs unset?

Basic (small data) data arrays etc. are good candidates for unset because memory won't become an issue. Larger data sets and/or anywhere the need to reclaim memory immediately is better for null. For example such large database requests can cannibalize your PHP memory ceiling very quickly if called multiple times in a function etc. which will cause page 500 errors from memory being full etc.. Therefore, unset should be preferred when speed is important (or in general) and when there is little concern for memory build up.

Example: Taking a large array and placing it into MemCache:

		    list($inv1, $inv2, $inv3, $inv4) = array_chunk($inventory_array), 
            ceil(count($val['inventory']) / 4));
			MemCache::set($cacheKeyInv1, $inv1, $expiry);
			MemCache::set($cacheKeyInv2, $inv2, $expiry);
			MemCache::set($cacheKeyInv3, $inv3, $expiry);
			MemCache::set($cacheKeyInv4, $inv4, $expiry);
			for ($i = 1; $i < 5; $i++) {
				${"inv" . $i} = null; // why not use unset ?
			}

The for loop is cleaning up the data, null or unset could be used, but since it is a large dataset, perhaps null is preferred as it will reclaim the memory quicker.

Solution 5 - Php

Using the code

$a = str_repeat('hello world ', 10000);

$start1 = microtime(true);
unset($a);
$stop1 = microtime(true);

$a = str_repeat('hello world ', 10000);

$start2 = microtime(true);
$a = null;
$stop2 = microtime(true);

echo 'unset time lap of '. ( $stop1 - $start1 ) .'<br>';
echo 'null time lap of '. ( $stop2 - $start2 ) .'<br>';

for 10 times:

unset time lap of 5.0067901611328E-6
null time lap of 1.1920928955078E-6

unset time lap of 9.5367431640625E-7
null time lap of 9.5367431640625E-7

unset time lap of 0
null time lap of 9.5367431640625E-7

unset time lap of 2.1457672119141E-6
null time lap of 1.1920928955078E-6

unset time lap of 2.1457672119141E-6
null time lap of 0

unset time lap of 9.5367431640625E-7
null time lap of 0

unset time lap of 1.9073486328125E-6
null time lap of 9.5367431640625E-7

unset time lap of 9.5367431640625E-7
null time lap of 0

unset time lap of 1.9073486328125E-6
null time lap of 9.5367431640625E-7
 
unset time lap of 0
null time lap of 0

Looks like null assignment has less processing time more often.

Solution 6 - Php

The difference is that assignment of null is assignment of null and not uninitialization. If you do not work on performance critical issue, you shut use unset, if you do test both possibility on your PHP version. Main difference came with PHP 7.4, and properties types, you can unset not nullable property, but you can't assign null.

class C {
    public int $value;
}

$c = new C();
var_dump(isset($c->value));   // false
$c->value = 5;
var_dump($c->value);          //5
unset($c->value);
//var_dump($c->value);       //Error: Typed property C::$value must not be accessed before initialization
var_dump(isset($c->value));  // false
$c->value = 5;
$c->value = null;            //Error Typed property C::$value must be int, null used

https://3v4l.org/VUVD1

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1469439View Question on Stackoverflow
Solution 1 - PhpJa͢ckView Answer on Stackoverflow
Solution 2 - PhpAshkan ArefiView Answer on Stackoverflow
Solution 3 - Phpalexandre-rousseauView Answer on Stackoverflow
Solution 4 - PhpMike QView Answer on Stackoverflow
Solution 5 - Php943AView Answer on Stackoverflow
Solution 6 - PhpAdam MátlView Answer on Stackoverflow