2011-04-29 75 views
76

count()是否确实计算了PHP数组的所有元素,还是将此值缓存到某处并仅检索?对于数组,PHP的count()函数是O(1)还是O(n)?

+6

为什么不测试它?它足够简单,可以做一个循环,将元素添加到数组中并每次计算并执行一些计时。 – 2011-04-29 17:26:47

+2

看看这个问题:http://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions – 2011-04-29 17:29:25

+0

谷歌关键字 - 这个问题也可以表述为:PHP count()迭代数组还是从数组属性检索计数? – 2015-09-01 12:07:41

回答

103

好了,我们可以看看源:

/ext/standard/array.c

PHP_FUNCTION(count)电话php_count_recursive(),这反过来又非递归阵列,这是这种方式实现来电zend_hash_num_elements()

ZEND_API int zend_hash_num_elements(const HashTable *ht) 
{ 
    IS_CONSISTENT(ht); 

    return ht->nNumOfElements; 
} 

所以你可以看到,它的为​​。

+5

虽然'IS_CONSISTENT(ht)'做了什么? – Matthew 2011-04-29 17:43:40

+1

谢谢!我不太清楚在源代码中我应该看看的位置或从何处获取源代码(而不必从存储库中检查它)。 – Dexter 2011-04-29 17:51:55

+3

@Matt它正在检查散列结构是否有效,正如我所见。它在zend_hash.c中定义,它也是O(1)。 – 2011-04-29 18:09:08

6

在PHP 5+中,长度存储在数组中,因此每次都不会进行计数。

编辑:你也可能会发现这个分析有趣:PHP Count Performance。虽然阵列的长度由阵列维护,但如果您打算多次呼叫count(),似乎仍然保持较快。

+0

我认为你可能是正确的,从PHP 5开始的变化。 但是,我还没有找到证明PHP 4是O(n)count();我只看到轶事评论。你能找到证明(例如PHP 4的count()实现)吗?谢谢, – 2016-01-16 00:46:06

3

PHP在内部存储数组的大小,但是如果你正在做一些类似的事情时,你仍然在做一个函数调用,哪一个比不做一个调用要慢,所以你需要将结果存储在一个变量中在循环中使用它:

例如,

$cnt = count($array); 
for ($i =0; $i < $cnt; $i++) { 
    foo($array[$i]); 
} 

此外,你不能始终确保count被称为阵列上。例如,如果在实现Countable的对象上调用该对象,则将调用该对象的count方法。

+0

作为一个后续行动,你可能想要阅读http://josephscott.org/archives/2010/01/php-count-performance/它基本上详细说明如何获得数组长度为o(1)以及重复的函数调用。 – TheClair 2011-04-29 17:32:51

+0

正在做一个函数调用总是比不做一个更慢?我不会惊讶地发现解释器有内联优化。 – corsiKa 2011-04-29 17:34:11

+1

'这个对象的计数方法将被称为',如果一个类实现了'Countable'接口,然后调用'count($ object)'和调用'$是同一件事的话,你可以这样解释一下 – 2014-08-02 09:09:40

相关问题