La funzione count () di PHP è O (1) o O (n) per gli array?


96

Fa count()davvero contare gli tutti gli elementi di un array PHP, o è questo valore memorizzato nella cache da qualche parte e appena viene recuperata?


6
Perché non provarlo? è abbastanza semplice fare un ciclo che aggiunge elementi a un array e conta ogni volta e fa un po 'di tempo.
Marc B

3
Dai un'occhiata a questa domanda: stackoverflow.com/questions/2473989/…
The Pixel Developer

Parole chiave di Google: questa domanda potrebbe anche essere formulata come segue: PHP count () esegue l'iterazione su un array o recupera il conteggio dalla proprietà dell'array?
jave.web

Risposte:


136

Bene, possiamo guardare la fonte:

/ext/standard/array.c

PHP_FUNCTION(count)chiamate php_count_recursive(), che a loro volta richiedono un zend_hash_num_elements()array non ricorsivo, che viene implementato in questo modo:

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

    return ht->nNumOfElements;
}

Quindi puoi vedere, è O(1)per $mode = COUNT_NORMAL.


6
Ma cosa IS_CONSISTENT(ht)fa?
Matteo

1
Grazie! Non ero del tutto sicuro di dove avrei dovuto cercare nel sorgente o dove ottenere il sorgente (senza doverlo controllare da un repository).
Dexter

3
@ Matt sta controllando se la struttura hash è valida, come posso vedere. È definito in zend_hash.c ed è anche O (1).
Vladislav Rastrusny

10
Non posso mancare di votare per qualcuno che cerca la risposta nel codice sorgente di PHP :)
Lamy

1
@Matt IS_CONSISTENT () è solo un controllo di integrità sull'array github.com/php/php-src/blob/PHP-5.3/Zend/zend_hash.c#L51
John Carter

7

In PHP 5+ la lunghezza è memorizzata nell'array, quindi il conteggio non viene eseguito ogni volta.

EDIT: Potresti anche trovare interessante questa analisi: PHP Count Performance . Sebbene la lunghezza dell'array sia mantenuta dall'array, sembra comunque che sia più veloce mantenerlo se hai intenzione di chiamare count()molte volte.


Penso che tu abbia ragione sul fatto che la modifica sia stata apportata a partire da PHP 5. Tuttavia, non ho ancora trovato la prova che PHP 4 fosse O (n) per count (); Vedo solo commenti aneddotici. Sei in grado di trovare una prova (ad esempio l'implementazione count () per PHP 4)? Grazie,
Kristopher Windsor

3

PHP memorizza internamente la dimensione di un array, ma stai ancora effettuando una chiamata di funzione quando è più lento che non crearne una, quindi ti consigliamo di memorizzare il risultato in una variabile se stai facendo qualcosa come usarlo in un ciclo continuo:

Per esempio,

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

Inoltre, non puoi sempre essere sicuro che countvenga chiamato su un array. Se viene chiamato su un oggetto che implementa, Countablead esempio, countverrà chiamato il metodo di quell'oggetto.


In seguito potresti voler leggere josephscott.org/archives/2010/01/php-count-performance Fondamentalmente descrive in dettaglio come ottenere la lunghezza dell'array è o (1) e l'impatto delle ripetute chiamate di funzione.
TheClair

1
fare una chiamata di funzione è sempre più lento che non farne una? Non sarei sorpreso di trovare l'interprete con l'ottimizzazione in linea.
corsiKa

1
the count method of that object will be called, puoi spiegare un po 'questo
Steel Brain

1
@SteelBrain se una classe implementa l' Countableinterfaccia, chiamare count($object)è la stessa cosa che chiamare $object->count(). Vedi 3v4l.org/oYSSC per esempio.
mfonda

you're still making a function call when which is slower than not making oneQuesta affermazione può essere sbagliata. Se stai eseguendo l'attraversamento manuale, questa è O(n)un'operazione. Ma se vuoi solo recuperare un valore pre calcolato, l'operazione è O(1).
Jamshad Ahmad il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.