## strange PHP behaviour with global array

In this forum members can discuss topics about specific programming languages.
mbr001
Posts: 3
Joined: Wed Dec 23, 2015 11:33 am

### strange PHP behaviour with global array

Hi all,
while trying to optimize a Project Euler problem,I stumbled upon a problem, I dont understand.
consider the following code

Code: Select all

<?php
set_time_limit(200);
$time_start = microtime(true); ini_set('memory_limit', '2048M');$x = 10000;
$a = makeArray($x);

$time_end = microtime(true); echo "Call makeArray(".$x.") : ".($time_end -$time_start)." s\n";

$time_start = microtime(true);$sum = sumArray($a);$time_end = microtime(true);
echo "Calculate with sumArray() : ".$sum." :".($time_end - $time_start)." s\n";$time_start = microtime(true);

$sum = 0; //$lim = count($a); for($i=0;$i<count($a);$i++) {$sum += $a[$i];
}

$time_end = microtime(true); echo "direct Calulation : ".$sum." : ".($time_end -$time_start)." s\n";

function makeArray($x) { for($i=0;$i<$x;$i++) {$a[] = $i; } return$a;
}

function sumArray(&$a) {$sum = 0;
//$lim = count($a);
for($i=0;$i<count($a);$i++)
{
$sum +=$a[$i]; } return$sum;
}

?>
In my opinion, both calculations should have roughly the same timing, but the output is:

Call makeArray(10000) : 0.0089700222015381 s
Calculate with sumArray() : 49995000 :10.526546001434 s
direct Calulation : 49995000 : 0.0033800601959229 s

I Expected that there would be a very slight overhead, because of calling the function and perhaps copying the array, but I thought that should be very small, if not unmeasureable at all.

So can anyone tell me, why the huge performance hit occurs?
Edit: I just figured out that it has something to do with calling the count() function in the loop. But I do not fully understand the effect. When using the outcommented line and comparing to the $lim variable in the loop, I get the following: Call makeArray(10000) : 0.0067830085754395 s Calculate with sumArray() : 49995000 :0.0027248859405518 s direct Calulation : 49995000 : 0.0012359619140625 s But I still dont get it, why this change impacts the function call this massive, while the effect in the direct calculation is comparable small... TripleM Posts: 382 Joined: Fri Sep 12, 2008 3:31 am ### Re: strange PHP behaviour with global array While the count function is O(1), it's still several times slower than using a variable. You're calling the count function 10000 times within the loop, so the effect is magnified. mbr001 Posts: 3 Joined: Wed Dec 23, 2015 11:33 am ### Re: strange PHP behaviour with global array Hello TripleM, thank you for your reply. TripleM wrote:While the count function is O(1), it's still several times slower than using a variable. You're calling the count function 10000 times within the loop, so the effect is magnified. So I realize that using count in a loop is a big mistake in terms of performance. But what still amazes me is the fact that replacing the count() by a precalculated variable in the "main" function changes the speed by a factor of roundabout 2.7 while in the function "sumArray()" it improves speed by the factor of roundabout 3829. Thus my original problem being solved (solution for Problem 72 (View Problem) runs in 53 s now instead of 10 minutes ) I would like to understand the inner workings of PHP in this case. euler Administrator Posts: 3316 Joined: Sun Mar 05, 2006 4:49 pm Location: Cheshire, England Contact: ### Re: strange PHP behaviour with global array I don't know the answer myself, so I'd like to know what is going on too. If I had to guess then I suspect it is to do with needing to continually "reach outside the function" each time you use count() to determine the size of the array. Because you are passing the array by reference then it may have to recalculate the dimension of the array each time the function is used, whereas using the count function with a local variable PHP knows it hasn't changed in size and so after the first call it caches the value. Interestingly, if I don't pass the array to sumArray by reference: sumArray(\$a) instead of sumArray(&\$a), then the time difference is negligible with the direct calculation. Also quite interesting on my machine is that if I remove the pass-by-reference but then explicitly declare the array as global: global$a, within the sumArray function, then it is about 50 ms slower than using the pass-by-reference.

impudens simia et macrologus profundus fabulae

TripleM
Posts: 382
Joined: Fri Sep 12, 2008 3:31 am

### Re: strange PHP behaviour with global array

Hm, I see what you mean. That is strange.

It doesn't appear to be anything to do with the count function (or what that function does) - it looks like someone else found the same applies even to an empty function, when a reference to a large array is used: https://gist.github.com/ihabunek/6375653

Edit - I suspect this may contain the answer: https://flyleafbd.wordpress.com/2011/06 ... variables/ . It seems as if creating a reference can, on certain occasions, still require creating a duplicate of the entire data, while conversely passing by value doesn't necessarily.

mbr001
Posts: 3
Joined: Wed Dec 23, 2015 11:33 am