2011-04-29 66 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

相關問題