2011-05-23 206 views
11

在今天的工作中,我曾與一個關於在範圍之間傳遞大量數據的拼貼爭論。 神話是在2個示波器之間傳遞時,引用使用更少的內存/ 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()」

正如你看到的,使用大量數據會消耗更多的內存返回比作爲參考更聰明,但問題是,爲什麼? 歡迎任何啓發:)

回答

9

這是由於php處理變量的方式,對於任何使用C或C++的人來說都有點違反直覺。

不建議通過引用傳遞比PHP更聰明。 PHP實際上並不複製數據,除非它需要(也就是說,如果有超過1個引用的變量,則更改變量的值),這種優化策略與共享內存頁面的寫時複製非常相似。

因此,假設您有一個變量,您可以在給定的腳本中多次傳值。如果你接着使用這個變量並通過引用傳遞它,你實際上覆制了變量,而不是僅僅獲得一個指向該對象的指針。

這是因爲內部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/

+0

這僅僅是給出答案,這是很好的一個。謝謝! :) – confiq 2011-05-25 18:33:47

+0

鏈接似乎死了:( 我想這是一個鏡像站點: http://porteightyeight.wordpress.com/2008/03/18/the-truth-about-php-variables/ – confiq 2013-02-03 09:28:38