unset和= null之间的区别

49 php

从一个随机的php.net帖子:

如果你正在做$ whatever = null; 那么你正在重写变量的数据.您可能会更快地释放/缩小内存,但它可能会更快地从真正需要它们的代码中窃取CPU周期,从而导致更长的总体执行时间.

显然这是无可争议的事实,所以也许有人会如此善良地解释.

我的意思是,什么,unset神奇地没有执行任何汇编指令,$whatever = null;而是?如上所述,答案和说法一样有用

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

Techno mumbo jumbo并不构成答案.

Ja͢*_*͢ck 64

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

$a = str_repeat('hello world ', 100);
unset($a);
var_dump($a);
Run Code Online (Sandbox Code Playgroud)

输出:

Notice: Undefined variable: a in xxx
NULL
Run Code Online (Sandbox Code Playgroud)

但是什么时候$a = null使用:

$a = str_repeat('hello world ', 100);
$a = null;
var_dump($a);
Run Code Online (Sandbox Code Playgroud)

输出:

NULL
Run Code Online (Sandbox Code Playgroud)

我也通过基准测试运行代码,发现它$a = nullunset()同类产品快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;
Run Code Online (Sandbox Code Playgroud)

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


Ash*_*efi 8

使用未设置时,内存使用和处理时间较少.

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


Mik*_*e Q 6

上面的答案很好,尤其是“两种方法之间的一个重要区别是 unset($a) 也会从符号表中删除 $a”的评论。

然而,我认为没有人在实际意义上真正完全回答了这个问题,因为他们没有描述两者是如何使用的。好吧,我想我们知道他们基本上都做同样的事情。为什么要使用其中一种而不是另一种?

无效的

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

取消设置()

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

什么时候应该使用 null 和 unset?

基本(小数据)数据数组等是取消设置的良好候选者,因为内存不会成为问题。较大的数据集和/或任何需要立即回收内存的地方更适合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 ?
            }
Run Code Online (Sandbox Code Playgroud)

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


Rou*_*dre 5

我做了一个简单的测试。

考虑这样一个简单的类:

class Cat{
    public $eyes  = 2;
    public $claws = 4;
    public $name  = "Kitty";
    public $sound = ['Meow', 'Miaou'];
}
Run Code Online (Sandbox Code Playgroud)

我运行此代码代码

$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 Code Online (Sandbox Code Playgroud)

在 1.95 运行并使用 233.29 内存

和这个

for($i = 10000000; $i > 0; --$i){
    $cat = new Cat;
    unset($cat);
}
Run Code Online (Sandbox Code Playgroud)

2.28运行,使用233.1内存

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