Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

the difference between unset and = null

Tags:

php

People also ask

What is unset used for?

unset() destroys the specified variables. The behavior of unset() inside of a function can vary depending on what type of variable you are attempting to destroy. If a globalized variable is unset() inside of a function, only the local variable is destroyed.

What is the unset key?

The unset function is used to destroy any other variable and same way use to delete any element of an array. This unset command takes the array key as input and removed that element from the array. After removal the associated key and value does not change. Syntax: unset($variable)

What's better at freeing memory with PHP unset () or $var Null?

null variable immediately frees the memory.

Does unset free memory PHP?

unset() does just what its name says - unset a variable. It does not force immediate memory freeing. PHP's garbage collector will do it when it see fits - by intention as soon, as those CPU cycles aren't needed anyway, or as late as before the script would run out of memory, whatever occurs first.


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.


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

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


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.


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.


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.