unset和= null之间的区别

时间:2012-12-02 07:00:32

标签: php

来自random php.net post

  

如果你正在做$ whatever = null;然后你正在重写变量   数据。您可能会更快地释放/缩小内存,但它可能会窃取CPU   从真正需要它们的代码中循环出来,产生一个   更长的总执行时间。

显然这是undisputed truth所以也许有人会如此善意地解释。

我的意思是,unset神奇地没有执行任何汇编指令而$whatever = null;呢?给出的答案和说

一样有用
  

$ whatever = null重置缓冲区和L1缓存,而unset清除缓冲区并重置L2缓存。

Techno mumbo jumbo并不构成答案。

5 个答案:

答案 0 :(得分:62)

两种方法之间的一个重要区别是unset($a)也会从符号表中删除$a;例如:

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

输出:

Notice: Undefined variable: a in xxx
NULL

但是当使用$a = null时:

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

输出:

NULL

我也通过基准测试运行代码,发现$a = null的速度比unset()快约6%。似乎更新符号表条目比删除它更快。

<强>附录

另一个区别(如这个小脚本中所示)似乎是每次调用后恢复了多少内存:

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;

当使用unset()时,只返回64字节的内存,而$a = null;释放除272字节内存以外的所有内存。我没有足够的知识知道为什么两种方法之间存在208字节的差异,但它仍然存在差异。

答案 1 :(得分:8)

使用未设置时,内存使用和处理时间较短。

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

答案 2 :(得分:4)

我做了一个简单的测试。

考虑这样一个简单的类:

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

我运行此代码

$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));
  

在1.95中运行并使用233.29内存

这个

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

在2.28中运行并使用233.1内存

值得一提的是,null方法运行得更快。

答案 3 :(得分:2)

上面的答案很棒,特别是这样评论:“这两种方法之间的重要区别是unset($ a)也会从符号表中删除$ a”。

但是,我认为没有人从实践意义上真正完全回答过该问题,因为他们没有描述两者的用法。好的,我想我们知道他们基本上都在做同一件事。为什么要使用一个?

尽管PHP自我管理内存/垃圾回收,但仍立即回收内存(以花费更长的时间为代价)。

取消设置()

通常建议使用它,因为它“在我可以使用它的时候”回收内存,因此被认为是更快的,因为它不会立即为它分配资源。

何时应使用null与未设置?

基本(小数据)数据阵列等是未设置的很好的候选对象,因为内存不会成为问题。较大的数据集和/或需要立即回收内存的任何地方,对于来说更好。例如,如果在函数中多次调用此类大型数据库请求,可能会很快蚕食您的PHP内存上限,这将导致内存已满等导致的第500页错误。因此,在以下情况下,首选 unset 速度很重要(或通常而言),并且几乎不需要考虑内存的增加。

示例:获取一个大型数组并将其放入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 ?
            }

for循环正在清理数据,可以使用null或unset,但是由于它是一个大型数据集,因此也许首选null,因为它将更快地回收内存。

答案 4 :(得分:1)

使用代码

$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>';

10次:

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

看起来空分配的处理时间更少。