2012-12-10 55 views
7

我遇到了一些看起來像是奇怪的性能問題。運行此代碼:爲什麼在這段代碼中通過引用慢?

<?php 

function test_ref(&$test) 
{ 
    for ($i = 0; $i < 100000; $i++) 
    { 
     $foo = "s" . rand(1, 1000); 
     if (!array_key_exists($foo, $test)) 
     { 
      $test[$foo] = array(); 
     } 
     $test[$foo][] = rand(1, 10); 
    } 
} 

function test() 
{ 
    $test = array(); 
    for ($i = 0; $i < 100000; $i++) 
    { 
     $foo = "s" . rand(1, 1000); 
     if (!array_key_exists($foo, $test)) 
     { 
      $test[$foo] = array(); 
     } 
     $test[$foo][] = rand(1, 10); 
    } 

    return $test; 
} 

$scriptstart = microtime(true); 
$test = array(); 
test_ref($test); 
$sum = 0; 

foreach ($test as $key => $val) 
{ 
    foreach ($val as $val2) 
    { 
     $sum += $val2; 
    } 
} 

echo "sum " . $sum . "<br>"; 
$scriptelapsed = microtime(true) - $scriptstart; 
echo "time taken " . $scriptelapsed . "<br>"; 

$scriptstart = microtime(true); 
$test = test(); 
$sum = 0; 

foreach ($test as $key => $val) 
{ 
    foreach ($val as $val2) 
    { 
     $sum += $val2; 
    } 
} 

echo "sum " . $sum . "<br>"; 
$scriptelapsed = microtime(true) - $scriptstart; 
echo "time taken " . $scriptelapsed . "<br>"; 

?> 

我得到這些結果:

sum 548521 
time taken 12.37544798851 
sum 551236 
time taken 0.29530310630798 

這是怎麼回事?這似乎與我將子數組插入數組的事實有關,但我不明白爲什麼通過引用傳遞應該慢得多。

(這是在PHP版本5.3.3-7 + squeeze14用了Suhosin補丁0.9.9.1)

(編輯:使用未設置變量固定的,還是一樣的結果)

+6

哪裏'$ array'來從? –

+1

按價值歸還不是免費的。 –

+0

我不知道答案(但我有興趣瞭解它),但我會注意到PHP中的引用不是指針。它們實際上是一種間接的層面。因此,通過使用參考,解釋器必須先查找參考,然後查找參考值。沒有參考,它少了一步。這可能是你在這裏看到的放緩的原因。 – troelskn

回答

1

你所訪問來自另一個作用域的值 - 這總是比只使用函數本身中定義的那些要慢。這裏是一個不錯的博客文章,解釋它,即使這不是它的主要話題:PHP internals: When does foreach copy?

1

這只是我的猜測,但我認爲,我們可以解釋這樣的:

  • 使用沒有提及當一個局部變量(直接指向內存),循環如下所示:
    • $ i = 0; $ foo = 499; $ test [499] = array(); $ test [499] [] = 2; 「提交」直接到存儲器
    • finaly,值$測試然後返回 - 使用參考值時,直接從存儲器指針
  • 讀,通過了可變就像是一個指針的指針(即最後指向一個內存)
    • 在這種情況下,循環如下所示:
    • $ i = 0; $ foo = 354; $ test [354] = array(); $ test [354] [] = 7;通過指針「提交」到內存到內存指針

我猜,因此至少有一個步驟neccessary與引用的變量工作時...