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.