Categories
Posts

PHP Count Performance

There was a question on the Utah PHP user group email list recently that went something like this: is calling count() on an array once and storing the result in a variable better/faster than calling count() multiple times?

I’d always thought that if you were going to need the count of an array more than once then it was best to store the result in a variable. This also felt intuitively correct, as count() was likely doing some amount of work to provide the requested data. But I’d never really done any testing to confirm this was the case, so I figured this was a good time to determine if this long-held belief was correct. The first step was to come up with some very basic test scripts. Here’s the first one that calls count() multiple times (multi count):

[sourcecode lang=”php”]
$data = array( ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’, ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ’10’ );

if ( count( $data ) > 1 ) { }

if ( count( $data ) > 10 ) { }

if ( count( $data ) > 20 ) { }

if ( count( $data ) > 30 ) { }

if ( count( $data ) > 40 ) { }

if ( count( $data ) > 50 ) { }

if ( count( $data ) > 100 ) { }
[/sourcecode]

The second script (single count) calls count() once:

[sourcecode lang=”php”]
$data = array( ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’, ‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’, ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ’10’ );

$num_data = count( $data );

if ( $num_data > 1 ) { }

if ( $num_data > 10 ) { }

if ( $num_data > 20 ) { }

if ( $num_data > 30 ) { }

if ( $num_data > 40 ) { }

if ( $num_data > 50 ) { }

if ( $num_data > 100 ) { }
[/sourcecode]

The idea was to make it simple and focus on count(). Next up was a few tests to see what PHP would do with these two chunks of code.

VLD – PHP ops

multi count: 75 ops
single count: 64 ops

To start with I used vld to see how many operations each one performed. This confirms the idea that multi count requires more work for PHP, in this case 11 more ops for the simple test case. It doesn’t provide specific weights to each op, but in general more ops means more work.

Memory

multi count: 115,720 bytes
single count: 115,704 bytes

On a whim I was curious if there was any memory usage difference. I tested that with a call to memory_get_peak_usage() at the end of each script. The specific number of bytes used isn’t important, just the difference. The multi count script used an extra 16 bytes. A very tiny difference to be sure, but a difference none the less.

Execution Time (100,000 times)

multi count: 0.28717994689941 seconds
single count: 0.10203385353088 seconds

For a final test I looped through the count/if section of the code 100,000 times to see if there was a difference in the execution time. Looping 100,000 times was to make any difference a bit more obvious. I limited it to the just the count/if section of the code because I didn’t want to include the time it took to initialize the array. I ran this test over and over and the results were fairly consistent.

The single count approach was faster by 0.185 seconds. This doesn’t sound like much, but the other way to look at this is that the multi count code was more than 2.5 times slower than the single count code. That’s a pretty big ratio.

Conclusion

After running these tests it seems pretty clear that if you need to reference count() data more than once it’s better to store that value in a variable and reference that instead of calling count() multiple times. The single count required few ops, less memory (by just a tiny amount), and executed faster.

Nice to see that my original thoughts on this are confirmed.

5 replies on “PHP Count Performance”

Which version of PHP are you using for this test? The performance of count()/sizeof() is supposed to be linear in PHP 5+ since the length of the array is maintained with the array rather than calculated by the function call. I wouldn’t be surprised though if calling count() once still makes a difference.

Good to know. I bet if you ran this test on PHP 4 you see an even bigger difference in execution time.

I should have noticed the use of memory_get_peak_usage(), that’s a PHP 5.2+ function.

Leave a Reply

Your email address will not be published. Required fields are marked *