如果你正在做$ whatever = null;然后你正在重写变量 数据。您可能会更快地释放/缩小内存,但它可能会窃取CPU 从真正需要它们的代码中循环出来,产生一个 更长的总执行时间。
显然这是undisputed truth所以也许有人会如此善意地解释。
我的意思是,unset
神奇地没有执行任何汇编指令而$whatever = null;
呢?给出的答案和说
$ whatever = null重置缓冲区和L1缓存,而unset清除缓冲区并重置L2缓存。
Techno mumbo jumbo并不构成答案。
答案 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)
使用未设置时,内存使用和处理时间较短。
答案 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
看起来空分配的处理时间更少。