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
PHP中unset和null的比较的更多相关文章
- win10 uwp Window.Current.Dispatcher中Current为null
本文说的是进行网络中异步界面出现的错误,可能带有一定的主观性和局限性,说的东西可能不对或者不符合每个人的预期.如果觉得我有讲的不对的,就多多包含,或者直接关掉这篇文章,但是请勿生气或者发怒吐槽,可以在 ...
- [转帖]shell 中的>/dev/null 2>&1 是什么鬼?
shell 中的>/dev/null 2>&1 是什么鬼? http://blog.jobbole.com/109355/ 背景 我们经常能在shell脚本中发现>/dev/ ...
- C++中 0 与 NULL 与 nullptr之间的关系,nullptr_t 的实现
C++中 0 与 NULL 与 nullptr之间的关系,nullptr_t 的实现 来源 http://blog.csdn.net/Virtual_Func/article/details/4975 ...
- 在python中是没有NULL的,取而代之的是None,它的含义是为空
在python中是没有NULL的,取而代之的是None,它的含义是为空
- webapi中session为null的解决方案
Session webapi中session为null的解决方案 在Global.asax里添加:开启Session功能(默认是不开启) 重写init方法 public class WebApiAp ...
- 160304-02、JS 中如何判断null 和undefined
JavaScript 中有两个特殊数据类型:undefined 和 null,下节介绍了 null 的判断,下面谈谈 undefined 的判断. 以下是不正确的用法: var exp = undef ...
- iOS之iOS中的(null)、<null>、 nil 的问题
摘要: 你有没有过这样的经历,就是界面上显示出类似<null>.(null)这样一些东西,有时候还会莫名其妙的闪退.反反复复真是曰了犬,今天来总结一下这个问题的解决方法 前段时间开发过 ...
- 我的Android进阶之旅------>android中service的onStartCommand()方法中intent为null的问题
今天在维护公司的一个APP的时候,突然爆了空指针异常, Caused by: java.lang.NullPointerException: Attempt to invoke virtual met ...
- 在Java中,return null 是否安全, 为什么?
Java代码中return value 为null 是不是在任何情况下都可以,为什么不会throw NullPointerException? Java语言层面:null值自身是不会引起任何问题的.它 ...
随机推荐
- 消息 245,级别 16,状态 1,第 1 行 在将 varchar 值 '2,8' 转换成数据类型 int 时失败。
错误问题: 消息 245,级别 16,状态 1,第 1 行在将 varchar 值 '2,8' 转换成数据类型 int 时失败. ps: 这是在后台分配菜单权限这个功能时出现的问题 一,解决方法: 将 ...
- ios开发之UIView和UIViewController
UIView 表示屏幕上的一块矩形区域,负责渲染区域的内容,并且响应该区域内发生的触摸事件.它在 iOS App 中占有绝对重要的地位,因为 iOS 中几乎所有可视化控件都是 UIView 的子类. ...
- js实现图片延迟加载原理
<img src="image/1188695.png" alt="taobao" trueImg="image/1.jpg" id= ...
- 2018-2-13-win10-UWP-你写我读
title author date CreateTime categories win10 UWP 你写我读 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17: ...
- for循环(C语言型)语法
- Nginx-LNMP架构搭建
目录 Nginx-LNMP架构搭建 LNMP架构概述 LNMP架构环境部署 部署LNMP 部署博客Wordpress 搭建知乎产品wecenter 搭建edusoho (修改域名及安装路径) 数据库拆 ...
- 【虚拟机】:"该虚拟机似乎正在使用中。 如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。否则,请按“取消(C)”按钮以防损坏。"
1.可能是由于上次使用虚拟机,没有正常关闭出现了这种情况,于是把问题复制粘贴搜了一下. 2.出现了如下可行的解决方法:把后缀名为.vmdk.lck的都删除掉. 3.然后再打开虚拟机就可以了.
- wxss 优先级
外部元素>内部元素>id选择器>class 选择器>元素选择器
- python3 实现堡垒机功能(并发执行命令及上传下载文件)
转载请注明出处,欢迎提出宝贵意见,谢谢! 功能介绍: 1.主机分组 登录后显示分组主机及主机数量 选择主机组后显示该主机组下所有主机信息,主机名及IP显示输入选择:1.执行命令利用线程并发组内所有主机 ...
- paper 147:Deep Learning -- Face Data Augmentation(一)
1. 在深度学习中,当数据量不够大时候,常常采用下面4中方法: (1)人工增加训练集的大小. 通过平移, 翻转, 加噪声等方法从已有数据中创造出一批"新"的数据.也就是Data ...