通过引用返回大数据或作为函数返回?

时间:2011-05-23 20:51:01

标签: php memory-management

今天在工作中我讨论了关于在范围之间传递大数据的拼贴画。 神话是,在两个范围之间传递时,引用使用较少的内存/ CPU使用率。我们建立一个合适的概念证明......所以:

function by_return($dummy=null) {
    $dummy = str_repeat("1",100 * 1024 * 1024);
    return $dummy;
}

function by_reference(&$dummy) {
    $dummy = null;
    $dummy = str_repeat("1",100 * 1024 * 1024);
}
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
//1 always returns: 105493696/105496656
$nagid = by_return();
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
unset($nagid);
//2 always returns:  105493696/210354184 even if we comment 1st part
by_reference($dummy);
echo memory_get_usage()."/".memory_get_peak_usage()."\n";
unset($dummy);

但似乎根据函数“memory_get_peak_usage()”

引用它会消耗更多内存

如您所见,使用大数据进行返回比使用作为参考更聪明但问题是,为什么? 欢迎任何启发:)

1 个答案:

答案 0 :(得分:9)

这是由于php处理变量的方式,对于使用C或C ++工作的人来说,这有点违反直觉。

不建议通过引用传递比PHP更聪明。除非需要,否则PHP实际上并不会复制数据(即,当对其进行多次引用时更改变量的值),这是一种非常类似于共享内存页面的写时复制的优化策略。

因此,假设您有一个变量,您在给定的脚本中多次传递值。如果你接受这个变量并通过引用传递它,你实际上是复制变量而不是只是获取指向对象的指针。

这是因为在内部,PHP zvals(PHP用于存储变量的数据结构)只能是引用变量或非引用变量。所以zval的ref_count字段是什么并不重要,因为它不是引用变量(zval结构的is_ref字段)。所以在内部,PHP被迫创建一个新的zval并将其is_ref字段设置为true,从而使内存加倍。

告诉你的同事不要试图超越PHP。通过引用传递,除非在整个代码中100%完美地完成将导致大量开销并使内存使用量加倍。

有关更详细的讨论,请参阅此链接:http://porteightyeight.com/2008/03/18/the-truth-about-php-variables/