我意识到第二种方法避免了函数调用的开销(更新,实际上是一种语言构造),但知道其中一种方法是否比另一种更好会很有趣。我的大部分代码都使用unset(),但最近我在网上找到了一些使用$var = null的体面类。

是否有一个首选的,理由是什么?


当前回答

<?php
$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”似乎更快。

PHP 5.4结果:

花了0.88389301300049秒 耗时2.1757180690765秒

PHP 5.3结果:

耗时1.7235369682312秒 用时2.9490959644318秒

PHP 5.2结果:

花了3.0069220066071秒 耗时4.7002630233765秒

PHP 5.1结果:

花了2.6272349357605秒 耗时5.0403649806976秒

在PHP 5.0和4.4中,情况开始有所不同。

5.0:

花了10.038941144943秒 耗时7.0874409675598秒

4.4:

耗时7.5352551937103秒 花了6.6245851516724秒

请记住,microtime(true)在PHP 4.4中不起作用,因此我必须使用php.net/microtime /示例#1中给出的microtime_float示例。

其他回答

它对数组元素有影响。

考虑这个例子

$a = array('test' => 1);
$a['test'] = NULL;
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";

这里,键“test”仍然存在。然而,在这个例子中

$a = array('test' => 1);
unset($a['test']);
echo "Key test ", array_key_exists('test', $a)? "exists": "does not exist";

密钥不再存在。

通过对变量执行unset()操作,您实际上已经将变量标记为“垃圾收集”(PHP实际上并没有这样的功能,但为了举例说明),因此内存不能立即可用。该变量不再存储数据,但堆栈仍然保持较大的大小。执行null方法几乎会立即丢弃数据并缩小堆栈内存。

这是我个人的经验,也是别人的经验。在这里查看unset()函数的注释。

我个人在循环的迭代之间使用unset(),这样我就不必在大小上有堆栈的延迟。数据消失了,但足迹还在。在下一次迭代时,内存已经被php占用,因此可以更快地初始化下一个变量。

<?php
$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”似乎更快。

PHP 5.4结果:

花了0.88389301300049秒 耗时2.1757180690765秒

PHP 5.3结果:

耗时1.7235369682312秒 用时2.9490959644318秒

PHP 5.2结果:

花了3.0069220066071秒 耗时4.7002630233765秒

PHP 5.1结果:

花了2.6272349357605秒 耗时5.0403649806976秒

在PHP 5.0和4.4中,情况开始有所不同。

5.0:

花了10.038941144943秒 耗时7.0874409675598秒

4.4:

耗时7.5352551937103秒 花了6.6245851516724秒

请记住,microtime(true)在PHP 4.4中不起作用,因此我必须使用php.net/microtime /示例#1中给出的microtime_float示例。

我仍然怀疑这一点,但我已经在我的脚本中尝试过,我正在使用xdebug来了解它将如何影响我的应用程序内存使用。 脚本是这样设置在我的函数:

function gen_table_data($serv, $coorp, $type, $showSql = FALSE, $table = 'ireg_idnts') {
    $sql = "SELECT COUNT(`operator`) `operator` FROM $table WHERE $serv = '$coorp'";
    if($showSql === FALSE) {
        $sql = mysql_query($sql) or die(mysql_error());
        $data = mysql_fetch_array($sql);
        return $data[0];
    } else echo $sql;
}

我在返回代码前添加了unset它给我160200 然后我尝试用$sql = NULL更改它,它给我:160224:)

但有一些独特的比较,当我不使用unset()或NULL, xdebug给我160144作为内存使用量

所以,我认为给line使用unset()或NULL将添加进程到您的应用程序,它将更好地保持原点与您的代码和减少变量,你正在使用尽可能有效。

如果我说错了请指正,谢谢

郑重声明,不包括花费的时间:

<?php
echo "<hr>First:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 
echo "<hr>Unset:<br>";
unset($x);
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 
echo "<hr>Null:<br>";
$x=null;
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n";

echo "<hr>function:<br>";
function test() {
    $x = str_repeat('x', 80000);
}
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 

echo "<hr>Reasign:<br>";
$x = str_repeat('x', 80000);
echo memory_get_usage() . "<br>\n";      
echo memory_get_peak_usage() . "<br>\n"; 

它返回

First:
438296
438352
Unset:
438296
438352
Null:
438296
438352
function:
438296
438352
Reasign:
438296
520216 <-- double usage.

结论,空内存和未设置空闲内存都是预期的(不仅在执行结束时)。另外,对变量重新赋值会在某个点上将值保存两次(520216对438352)