PHP中unset和null的比较

起因

因为感兴趣于unset($var)和$var=null的区别,于是找了一个stackoverflow高分问题及答案,翻译以供参考。

注:以下的问题和答案翻译自http://stackoverflow.com/questions/584960/whats-better-at-freeing-memory-with-php-unset-or-var-null

问题篇

Q:

我意识到第二个方法避免了函数调用的消耗(更新,实际是语言结构),但是我对于哪一个更好很有兴趣。我过去常常使用unset(),但是我看到很多受人尊敬的类使用$var=null替代。哪一个更适合为什么?

答案篇

A1

unset就像其名字所说的一样-删除一个变量。他不强制立即释放缓存。PHP的“垃圾”在适当的时候将会回收-出于速度的角度考虑,在CPU周期或者直到内存耗尽之前,无论发生什么,都不释放内存。

如果你正在使用$whatever=null,将会重写变量的数据。你本想使内存释放、缩小地更快,但是可能会占用CPU周期,导致总体执行时间更长。

2013年后,PHP Manual不再包含这个区块。

值得注意的是:PHP5.3之前,如果你有两个处于循环引用的对象,比如是“父子”类的关系,父类实例调用unset方法,将不会释放使用父类引用的子类的内存。(当父实例被垃圾回收时,也不会释放内存。)

上边那句话结合代码就很好理解了:

class Test{
    public $var = 'test variable';
}
while(true){
    $test = new Test();
    $test->test = $test;
    unset($test);
}

以上代码在PHP5.3之前,运行后,内存占用持续增加,最终导致 “PHP Fatal error: Allowed memory size of xxxxx bytes exhausted”。但这并不是这篇文章的重点(作者注:之后的博客会介绍自己对“PHP垃圾回收”的理解),暂且只列出的解决办法:

class Test{
    public $var = 'test variable';
}
while(true){
    $test = new Test();
    $test->test = $test;
    unset($test->test);//先删除掉引用变量
    unset($test);
}

使用unset($var)会把$var从符号表删除。比如:

$var = 'hello world';
unset($var);
var_dump($var);
//output:undefined $var

当使用$a=null时:

$var = 'hello world';
$var = null;
var_dump($var);
//output:null

看起来$var=null比unset($var)要快一些:因为更新符号表条目比删除它更快(作者注:PHP版本不同而不同)。

当你删除一个不存在的变量时,将会触发一个错误,变量表达式的值将也会是null。

如果一个变量设置成了null,仍将是一个的普通变量。

A2

unset实际上不是一个函数,而是一个语言结构体。

不考虑性能,使用unset使你的代码更加清晰。

A3

有回答者做了一个实验比较unset和赋值null,实验代码如下,实验PHP版本包括PHP5.1-5.4,PHP5.0和PHP4.4,我对PHP5.6、PHP7.0、PHP7.1作了补充(作者注:实验结果可能跟机器配置有关系)。

$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    $a = 'a';
    $a = NULL;
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";

$start = microtime(true);
for ($i = 0; $i < 10000000; $i++) {
    $a = 'a';
    unset($a);
}
$elapsed = microtime(true) - $start;
echo "took $elapsed seconds\r\n";
版本 null执行时间(s) unset执行时间(s) null和unset哪个更快
PHP7.1 0.22593188285828 0.19007802009583 unset
PHP7.0 0.54828405380249 0.60010099411011 null
PHP5.6 0.72876906394958 1.9859180450439 null
PHP5.4 0.88389301300049 2.1757180690765 null
PHP5.3 1.7235369682312 2.9490959644318 null
PHP5.2 3.0069220066071 4.7002630233765 null
PHP5.1 2.6272349357605 5.0403649806976 null
PHP5.0 10.038941144943 7.0874409675598 unset
PHP4.4 7.5352551937103 6.6245851516724 unset

翻译自:

http://stackoverflow.com/questions/584960/whats-better-at-freeing-memory-with-php-unset-or-var-null

相关文章

文章浏览阅读8.4k次,点赞8次,收藏7次。SourceCodester Onl...
文章浏览阅读3.4k次,点赞46次,收藏51次。本文为大家介绍在...
文章浏览阅读1.1k次。- php是最优秀, 最原生的模板语言, 替代...
文章浏览阅读1.1k次,点赞18次,收藏15次。整理K8s网络相关笔...
文章浏览阅读1.2k次,点赞22次,收藏19次。此网络模型提供了...
文章浏览阅读1.1k次,点赞14次,收藏19次。当我们谈论网络安...