為了實驗傳參考和傳值的效能,我使用了這個腳本。結論如下。
#!/usr/bin/php
<?php
function sum($array,$max){ // 參考用,使用:「&$array」
$sum=0;
for ($i=0; $i<2; $i++){
#$array[$i]++; // 取消註解此行以修改函數內的陣列。
$sum += $array[$i];
}
return ($sum);
}
$max = 1E7 // 1000 萬個資料點。
$data = range(0,$max,1);
$start = microtime(true);
for ($x = 0 ; $x < 100; $x++){
$sum = sum($data, $max);
}
$end = microtime(true);
echo "Time: ".($end - $start)." s\n";
/* 執行時間:
# 傳遞方式 修改? 時間
- ------- --------- ----
1 值傳遞 否 56 us
2 參考傳遞 否 58 us
3 值傳遞 是 129 s
4 參考傳遞 是 66 us
結論:
1. PHP 在零複製/寫入時複製方面已經很聰明。函數呼叫不會複製資料,除非需要複製;資料只會在寫入時複製。這就是為什麼 #1 和 #2 花費的時間相似,而 #3 比 #4 花費的時間長 200 萬倍的原因。
[您永遠不需要使用 &$array 來要求編譯器執行零複製優化;它可以自行判斷。]
2. 您可以使用 &$array 來告訴編譯器「函數可以覆寫我的參數,我不再需要原始參數」。當我們有大量記憶體需要複製時,這可能會對效能產生巨大影響。
(這是 C 中唯一的方式,陣列總是作為指標傳遞)
3. & 的另一個用途是指定資料應該*回傳*的位置。(例如,exec() 所使用的)。
(這是一種 C 語言風格的傳遞指標作為輸出的方式,而 PHP 函數通常會回傳複雜類型,或在陣列中回傳多個答案)
4. 只有函數定義有 & 是沒有幫助的。呼叫者應該也有,至少作為語法糖。否則會導致程式碼難以閱讀:因為讀取函數呼叫的人不會預期它是以傳參考方式傳遞的。目前,必須以註解撰寫傳參考的函數呼叫,如下所示:
$sum = sum($data,$max); // 警告,$data 以傳參考方式傳遞,可能會被修改。
5. 有時,傳參考應該由呼叫者選擇,而不是函數定義。PHP 不允許這樣做,但讓呼叫者決定以參考方式傳遞資料將是有意義的。也就是說,「我不再需要這個變數了,可以覆寫記憶體」。
*/
?>