Performance Implications of count()
Posted: Wed Aug 02, 2006 4:13 pm
So continuing my series of "Performance Implications of" this time we look to count().
The psychology of programming comes into play here. When I first started programming in PHP I used to use sizeof() instead of count(). Partly this was because I was programming in C++ mainly and the other reason was because count() sounds like an expensive operation where sizeof() less so. Of course any PHP dev worth their salt will know that sizeof() is just an alias of count() and are besides the name exactly the same. But one question always lumbered in my mind does count() count? Or does PHP monitor the size of the array as it is operated upon and count() is simply used to return that internal data? I was pretty sure that the latter was the case, lets see if I am right.
Here's the code:
This performs 4 different tests:
Here is the output:
The results show that 50 000 calls to count() an array 2700 elements in length is faster than a call to a function that returns 16!
There is no significant difference between count() and sizeof().
Using an array as an argument is consideribly more expensive.
Hope you learnt something folks.
The reason I did this was because I am creating a class that implements ArrayAccess, Iterator and Countable interfaces and I wondered if I could improve performance of calls to count by caching the length of the array private to my class but the reality is had I done that it would have likely slowed the performance of my class overall
The psychology of programming comes into play here. When I first started programming in PHP I used to use sizeof() instead of count(). Partly this was because I was programming in C++ mainly and the other reason was because count() sounds like an expensive operation where sizeof() less so. Of course any PHP dev worth their salt will know that sizeof() is just an alias of count() and are besides the name exactly the same. But one question always lumbered in my mind does count() count? Or does PHP monitor the size of the array as it is operated upon and count() is simply used to return that internal data? I was pretty sure that the latter was the case, lets see if I am right.
Here's the code:
Code: Select all
function microtime_float()
{
list($usec, $sec) = explode(' ', microtime());
return (float)($usec + $sec);
}
$array = array(1,5,6,3,7,8,3,6,7,3,1,5,7,8,4,2,5,1............ // it continues for a while
echo 'Array is ' . count($array) . " elements in length.\n\n\n";
/**
* *****************************************
*/
echo "COUNT()\n";
$time = array();
for ($i=0, $j=10; $i<$j; $i++) {
$k = 0;
$time['start'] = microtime_float();
for (;$k<50000; $k++) {
count($array);
}
$time['end'] = microtime_float();
$time['length'][] = $time['end'] - $time['start'];
}
print_r($time['length']);
flush();
echo "\n\n\n";
/**
* *****************************************
*/
echo "SIZEOF()\n";
$time = array();
for ($i=0; $i<$j; $i++) {
$k = 0;
$time['start'] = microtime_float();
for (;$k<50000; $k++) {
sizeof($array);
}
$time['end'] = microtime_float();
$time['length'][] = $time['end'] - $time['start'];
}
print_r($time['length']);
flush();
echo "\n\n\n";
/**
* *****************************************
*/
echo "GETINTWITHARRAYPARAM()\n";
$time = array();
function getIntWithArrayParam($a)
{
return 16;
}
for ($i=0; $i<$j; $i++) {
$k = 0;
$time['start'] = microtime_float();
for (;$k<50000; $k++) {
getIntWithArrayParam($array);
}
$time['end'] = microtime_float();
$time['length'][] = $time['end'] - $time['start'];
}
print_r($time['length']);
flush();
echo "\n\n\n";
/**
* *****************************************
*/
echo "GETINT()\n";
$time = array();
function getInt()
{
return 16;
}
for ($i=0; $i<$j; $i++) {
$k = 0;
$time['start'] = microtime_float();
for (;$k<50000; $k++) {
getInt();
}
$time['end'] = microtime_float();
$time['length'][] = $time['end'] - $time['start'];
}
print_r($time['length']);
flush();- Calling count() on a large array
- Calling sizeof() on a large array
- Calling of a user function that returns 16 with $array as the argument.
- Calling of a user function that returns 16 with no arguments
Here is the output:
Code: Select all
Array is 2700 elements in length.
COUNT()
Array
(
[0] => 0.0332798957825
[1] => 0.0332040786743
[2] => 0.0331971645355
[3] => 0.0338530540466
[4] => 0.0339250564575
[5] => 0.0339081287384
[6] => 0.0338890552521
[7] => 0.0338859558105
[8] => 0.0338299274445
[9] => 0.03391289711
)
SIZEOF()
Array
(
[0] => 0.0334188938141
[1] => 0.0333170890808
[2] => 0.0333638191223
[3] => 0.0333349704742
[4] => 0.0333120822906
[5] => 0.0340440273285
[6] => 0.0340280532837
[7] => 0.0342969894409
[8] => 0.0340049266815
[9] => 0.0340030193329
)
GETINTWITHARRAYPARAM()
Array
(
[0] => 0.0572888851166
[1] => 0.0563662052155
[2] => 0.0563371181488
[3] => 0.0576510429382
[4] => 0.0576648712158
[5] => 0.0571188926697
[6] => 0.0576598644257
[7] => 0.0571818351746
[8] => 0.057657957077
[9] => 0.0562329292297
)
GETINT()
Array
(
[0] => 0.0364010334015
[1] => 0.0363349914551
[2] => 0.0363218784332
[3] => 0.0364139080048
[4] => 0.0369350910187
[5] => 0.0371720790863
[6] => 0.0372090339661
[7] => 0.0372529029846
[8] => 0.0372650623322
[9] => 0.0362319946289
)There is no significant difference between count() and sizeof().
Using an array as an argument is consideribly more expensive.
Hope you learnt something folks.
The reason I did this was because I am creating a class that implements ArrayAccess, Iterator and Countable interfaces and I wondered if I could improve performance of calls to count by caching the length of the array private to my class but the reality is had I done that it would have likely slowed the performance of my class overall