Verifica di arrays vuoti: count vs empty

Questa domanda su " Come capire se un arrays PHP è vuoto " mi ha fatto pensare a questa domanda

C'è un motivo per cui il count dovrebbe essere usato al posto di empty quando si determina se un arrays è vuoto o no?

Il mio pensiero personale sarebbe se i 2 sono equivalenti per il caso di arrays vuoti che dovresti usare empty perché dà una risposta booleana a una domanda booleana. Dalla domanda collegata sopra, sembra che count($var) == 0 sia il metodo popolare. Per me, anche se tecnicamente corretto, non ha senso. Ad esempio D: $ var, sei vuoto? A: 7 . Hmmm …

C'è una ragione per cui dovrei usare count == 0 o solo una questione di gusti personali?

Come indicato da altri nei commenti per una risposta ora cancellata, il count avrà impatti sulle performance per i grandi arrays perché dovrà contare tutti gli elementi, mentre il empty può fermarsi non appena sa che non è vuoto. Quindi, se danno gli stessi risultati in questo caso, ma il count è potenzialmente inefficiente, perché dovremmo usare count($var) == 0 ?

Generalmente uso empty . Non sono sicuro del motivo per cui le persone utilizzerebbero davvero il count: se l'arrays è grande, il count impiega più tempo / ha un sovraccarico maggiore. Se è semplicemente necessario sapere se l'arrays è vuoto, utilizzare empty.

Ero curioso di vedere quale era in realtà più veloce, quindi ho creato una semplice sceneggiatura per confrontare queste funzioni.

 <?php function benchmark($name, $iterations, $action){ $time=microtime(true); for($i=0;$i<=$iterations;++$i){ $action(); } echo $name . ' ' . round(microtime(true)-$time, 6) . "\n"; } $iterations = 1000000; $x = arrays(); $y = range(0, 10000000); $actions = arrays( "Empty empty()" => function() use($x){ empty($x); }, "Empty count()" => function() use($x){ count($x); }, "Full empty()" => function() use($y){ empty($y); }, "Full count()" => function() use($y){ count($y); }, ############ "IF empty empty()" => function() use($x){ if(empty($x)){ $t=1; } }, "IF empty count()" => function() use($x){ if(count($x)){ $t=1; } }, "IF full empty()" => function() use($y){ if(empty($y)){ $t=1; } }, "IF full count()" => function() use($y){ if(count($y)){ $t=1; } }, ############ "OR empty empty()" => function() use($x){ empty($x) OR $t=1; }, "OR empty count()" => function() use($x){ count($x) OR $t=1; }, "OR full empty()" => function() use($y){ empty($y) OR $t=1; }, "OR full count()" => function() use($y){ count($y) OR $t=1; }, ############ "IF/ELSE empty empty()" => function() use($x){ if(empty($x)){ $t=1; } else { $t=2; } }, "IF/ELSE empty count()" => function() use($x){ if(count($x)){ $t=1; } else { $t=2; } }, "IF/ELSE full empty()" => function() use($y){ if(empty($y)){ $t=1; } else { $t=2; } }, "IF/ELSE full count()" => function() use($y){ if(count($y)){ $t=1; } else { $t=2; } }, ############ "( ? : ) empty empty()" => function() use($x){ $t = (empty($x) ? 1 : 2); }, "( ? : ) empty count()" => function() use($x){ $t = (count($x) ? 1 : 2); }, "( ? : ) full empty()" => function() use($y){ $t = (empty($y) ? 1 : 2); }, "( ? : ) full count()" => function() use($y){ $t = (count($y) ? 1 : 2); } ); foreach($actions as $name => $action){ benchmark($name, $iterations, $action); } //END 

Da quando lo stavo facendo ho anche provato a controllare le performance facendo operazioni che sarebbero normalmente associate a count () / empty ()

Utilizzando PHP 5.4.39:

 Empty empty() 0.118691 Empty count() 0.218974 Full empty() 0.133747 Full count() 0.216424 IF empty empty() 0.166474 IF empty count() 0.235922 IF full empty() 0.120642 IF full count() 0.248273 OR empty empty() 0.123875 OR empty count() 0.258665 OR full empty() 0.157839 OR full count() 0.224869 IF/ELSE empty empty() 0.167004 IF/ELSE empty count() 0.263351 IF/ELSE full empty() 0.145794 IF/ELSE full count() 0.248425 ( ? : ) empty empty() 0.169487 ( ? : ) empty count() 0.265701 ( ? : ) full empty() 0.149847 ( ? : ) full count() 0.252891 

Utilizzando HipHop VM 3.6.1 (dbg)

 Empty empty() 0.210652 Empty count() 0.212123 Full empty() 0.206016 Full count() 0.204722 IF empty empty() 0.227852 IF empty count() 0.219821 IF full empty() 0.220823 IF full count() 0.221397 OR empty empty() 0.218813 OR empty count() 0.220105 OR full empty() 0.229118 OR full count() 0.221787 IF/ELSE empty empty() 0.221499 IF/ELSE empty count() 0.221274 IF/ELSE full empty() 0.221879 IF/ELSE full count() 0.228737 ( ? : ) empty empty() 0.224143 ( ? : ) empty count() 0.222459 ( ? : ) full empty() 0.221606 ( ? : ) full count() 0.231288 

Conclusioni se usi PHP:

  1. empty () è molto più veloce di count () in entrambi gli scenari, con una matrix vuota e popolata

  2. count () esegue lo stesso con un arrays pieno o vuoto.

  3. Fare un semplice IF o solo un'operazione booleana è la stessa cosa.

  4. IF / ELSE è leggermente più efficiente di (?:). A less che non stiate facendo miliardi di iterazioni con espressioni nel mezzo, è completamente insignificante.

Conclusioni se stai usando HHVM:

  1. empty () è un teeny-weeny un po 'più veloce di count () ma insignificante.

    [Il resto è lo stesso di PHP]

In conclusione della conclusione, se hai solo bisogno di sapere se l'arrays è vuoto usa sempre empty ();

Questo è stato solo un curioso test fatto semplicemente senza prendere in considerazione molte cose. È solo una prova di concetto e potrebbe non riflettere le operazioni in produzione.

Penso che sia solo una preferenza personale. Alcune persone potrebbero dire che empty è più veloce (es. http://jamessocol.com/projects/count_vs_empty.php ) mentre altri potrebbero dire che count è meglio dato che è stato originariamente creato per gli arrays. empty è più generale e può essere applicato ad altri tipi.

php.net fornisce il seguente avviso per count però:

count () può restituire 0 per una variabile che non è impostata, ma può anche restituire 0 per una variabile che è stata inizializzata con una matrix vuota. Utilizzare isset () per verificare se è impostata una variabile.

In altre parole, se la variabile non è impostata, riceverai un avviso da PHP che dice che non è definito. Pertanto, prima di utilizzare il count , sarebbe preferibile controllare la variabile con isset . Questo non è necessario con empty .

C'è un motivo per cui il count dovrebbe essere usato al posto di vuoto quando si determina se un arrays è vuoto o no?

C'è, quando devi fare qualcosa sull'arrays non vuoto sapendo che è la dimensione:

 if( 0 < ( $cnt = count($arrays) ) ) { echo "Your arrays size is: $cnt"; } else echo "Too bad, your arrays is empty :("; 

Ma non consiglierei di usare il count, a less che tu non sia sicuro al 100% che ciò che stai contando è un arrays. Ultimamente ho eseguito il debug del codice, in cui la function di errore restituiva FALSE invece dell'arrays vuoto e ciò che ho scoperto era:

 var_dump(count(FALSE)); 

produzione:

 int 1 

Quindi da allora sto usando empty o if(arrays() === $arrays) per essere sicuro di avere una matrix vuota.

count() sembra funzionare meglio con interfacce tipo arrays che implementano ArrayAccess/Countable . empty() restituisce true per questi tipi di oggetti anche se non hanno elementi. In genere queste classi implementano l'interface Countable , quindi se la domanda è "Questa raccolta contiene elementi?" senza fare un'ipotesi sull'implementazione, allora count() è un'opzione migliore.

In alternativa, puoi lanciare la variabile come booleana (implicitamente o esplicitamente):

 if( $value ) { // arrays is not empty } if( (bool) $value ) { // arrays is still not empty } 

Questo metodo genera un E_NOTICE se la variabile non è definita, analogamente a count() .

Per ulteriori informazioni, consultare la pagina del manuale PHP sul confronto dei tipi .

La mia preferenza personale è più per l'eleganza della codifica (in relazione al mio caso d'uso specifico). Sono d'accordo con Dan McG visto che count () non risponde con il tipo di dati corretto (in questo caso boolean) per il test in questione costringendo lo sviluppatore a scrivere più codice per riempire un'istruzione "if".

Che questo abbia un impatto significativo sulle performance è discutibile solo per arrays estremamente grandi (che probabilmente non avranno abbastanza allocazione di memory per lo less nella maggior parte dei setup).

In particolare quando si tratta dell'arrays $ _POST di PHP, sembra molto più "logico", a mio parere, scrivere / vedere:

 if ( !empty ( $_POST ) ) { // deal with postdata } 

Spero che questo possa aiutare qualcuno anche se è già stato risposto (e discusso su cosa). Nel mio scenario personale, so che tutti i miei arrays hanno tutti 7 elementi (i controlli sono stati fatti prima nel mio codice) e sto eseguendo un arrays_diff che ovviamente restituisce un arrays di zero quando è uguale.

Ho avuto 34 secondi per il count e 17 secondi per il empty . Entrambi mi danno gli stessi calcoli, quindi il mio codice è ancora valido.

Tuttavia puoi anche provare il == o === come in PHP – Controlla se due arrays sono uguali . La cosa migliore che vorrei dire è provare count vs empty vs == empty arrays , quindi vedere quale dà i tuoi migliori perfs. Nel mio caso il count stato il più lento, quindi ora sto usando empty … controllerò serialize successiva

Non vi è alcun motivo valido per preferire il count($myArray) == 0 su empty($myArray) . Hanno semantica identica. Alcuni potrebbero trovare uno più leggibile rispetto all'altro. Uno potrebbe funzionare marginalmente meglio dell'altro ma non è probabile che sia un fattore significativo nella maggior parte delle applicazioni di php. Per tutti gli scopi pratici, la scelta è una questione di gusti.

A volte l'uso di vuoto è un must. Ad esempio questo codice:

 $myarrays = arrays(); echo "myarrays:"; var_dump($myarrays); echo "<br>"; echo "case1 count: ".count($myarrays)."<br>"; echo "case1 empty: ".empty($myarrays)."<br>"; $glob = glob('sdfsdfdsf.txt'); echo "glob:"; var_dump($glob); echo "<br>"; echo "case2 count: ".count($glob)."<br>"; echo "case2 empty: ".empty($glob); 

Se si esegue questo codice in questo modo: http://phpfiddle.org/main/code/g9x-uwi

Ottieni questo risultato:

 myarrays:arrays(0) { } case1 count: 0 case1 empty: 1 glob:bool(false) case2 count: 1 case2 empty: 1 

Quindi se count l'output glob vuoto ottieni output errato. Dovresti controllare per il vuoto.

Dalla documentazione globale :

Restituisce un arrays contenente i file / le directory corrispondenti, un arrays vuoto se nessun file corrisponde o FALSE in caso di errore.
Nota: su alcuni sisthemes è imansible distinguere tra una corrispondenza vuota e un errore.

Controlla anche questa domanda: Perché contare (false) restituire 1?

Mi sono rifatto la testa ragazzi, grazie.

Ok, non c'è differenza tra l'uso di empty e il count . Tecnicamente, il count dovrebbe essere usato per gli arrays, e empty potrebbe essere usato per matrici e stringhe. Quindi, nella maggior parte dei casi, sono intercambiabili e se vedi i documenti php, vedrai la list dei suggerimenti dei count se sei empty e viceversa.

Poiché una variabile analizzata come negativa restituirebbe int(1) con count()

Io preferisco ($arrays === [] || !$arrays) per testare un arrays vuoto.

Sì, dovremmo aspettarci un arrays vuoto, ma non dovremmo aspettarci una buona implementazione sulle funzioni senza tipi di return forzati.

Esempi con count()

 var_dump(count(0)); > int(1) var_dump(count(false)); > int(1)