Napotkałem coś, co wydaje się dziwnym problemem wydajności. Uruchomienie tego kodu:Dlaczego przekazywanie przez odniesienie jest wolniejsze w tym kodzie?
<?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>";
?>
mogę uzyskać te wyniki:
sum 548521
time taken 12.37544798851
sum 551236
time taken 0.29530310630798
Co tu się dzieje? Wydaje się, że jest to związane z tym, że wstawiam pod-tablice do tablicy, chociaż nie rozumiem, dlaczego przekazywanie przez odniesienie powinno być o wiele wolniejsze.
(jest to na PHP Version 5.3.3-7 + squeeze14 z Suhosin patch 0.9.9.1)
(edit: stałe za pomocą zmiennych wyłączony, wciąż ten sam wynik)
Gdzie '$ array' przyjść od? –
Powracanie według wartości nie jest bezpłatne. –
Nie znam odpowiedzi (ale byłbym zainteresowany poznaniem jej), ale chciałbym zauważyć, że odniesienia w PHP nie są wskaźnikami. Są w rzeczywistości poziomem pośrednictwa. Korzystając z referencji, tłumacz najpierw musi przejrzeć referencję, a następnie sprawdzić podaną wartość. Bez referencji jest o krok mniejszy. To może być przyczyną spowolnienia, które tu widzisz. – troelskn