Cosa c'è di più veloce e migliore per determinare se esiste una chiave dell'array in PHP?


157

Considera questi 2 esempi ...

$key = 'jim';

// example 1
if (isset($array[$key])) {
    // ...
}

// example 2    
if (array_key_exists($key, $array)) {
    // ...
}

Sono interessato a sapere se uno di questi è meglio. Ho sempre usato il primo, ma ho visto molte persone usare il secondo esempio su questo sito.

Quindi, qual è la migliore? Più veloce? Intenzione più chiara?


Non ho eseguito alcun benchmark, no. Dovrei avere prima di chiedere?
alex

4
issetnon si comporterà mai esattamente come array_key_exists, l'esempio di codice che presumibilmente lo fa comportare identicamente genera un Avviso se la chiave non esiste.
ingannare

Che dire in_array? maettig.com/1397246220
DanMan

1
@DanMan, in_arrayè O(n)perché controlla i non valori delle chiavi. Saranno quasi sempre più lenti a meno che tu non nsia estremamente piccolo.
Pacerier

Perché no $array[$key] === null?
Pacerier,

Risposte:


237

isset()è più veloce, ma non è lo stesso di array_key_exists().

array_key_exists()controlla puramente se la chiave esiste, anche se il valore è NULL.

Mentre isset() che restituirà falsese la chiave esiste e il valore è NULL.


6
Hai risorse specifiche che sostengono che isset sia più veloce?
Francesco Pasa,

@Francesco Pasa Basta pensarci un po '. issetnon è una funzione di ricerca di array, controlla solo la presenza di una variabile nella tabella dei simboli e non ripeterà l'array. array_key_existsd'altra parte ripeterà / cercherà le chiavi nella prima dimensione dell'array specificato.
Pioggia il

@Rain sono abbastanza sicuro array_key_exists()che controllerà solo se la chiave è nell'array, il che significa che non farà una ricerca poiché è una tabella hash.
Francesco Pasa,

@FrancescoPasa Bene, "cerca le chiavi" è ciò che dice la documentazione di PHP. A parte questo, non so dire se "cercarli" significhi qualcosa di completamente diverso da ciò che significa per me.
Pioggia il

32

Se sei interessato ad alcuni test che ho fatto di recente:

https://stackoverflow.com/a/21759158/520857

Sommario:

| Method Name                              | Run time             | Difference
=========================================================================================
| NonExistant::noCheckingTest()            | 0.86004090309143     | +18491.315775911%
| NonExistant::emptyTest()                 | 0.0046701431274414   | +0.95346080503016%
| NonExistant::isnullTest()                | 0.88424181938171     | +19014.461681183%
| NonExistant::issetTest()                 | 0.0046260356903076   | Fastest
| NonExistant::arrayKeyExistsTest()        | 1.9001779556274      | +209.73055713%

IMPORTANTE: il timing di arrayKeyExists è stato scoperto per essere molto sbagliato - stava controllando il valore non la chiave - segui quel link per il timing rivisto in 7.1, che è molto meglio. (Sarebbe anche meglio nelle precedenti versioni di php, se Populus avesse ripetuto quel test.)
ToolmakerSteve

19

Bene, la differenza principale è che isset()non tornerà trueper le chiavi dell'array che corrispondono a un valore null, mentre lo array_key_exists()fa.

L'esecuzione di un piccolo benchmark indica che isset()è più veloce ma potrebbe non essere del tutto preciso.


1
Puoi eseguire nuovamente il benchmark con il più corretto "(isset ($ array [$ i]) || $ array [$ i] === null)"?
Tomalak,

Oh, e pubblicheresti un'indicazione della differenza di prestazioni mostrata dalle due varianti? Grazie!
Tomalak,

1
@Tomalak, ho eseguito l'esempio che hai suggerito e afferma che array_key_exists () è più veloce di isset () con || operatore. codepad.org/5qyvS93x
alex

1
Dai tempi morti ... ma ho anche rieseguito il benchmark e fatto una modifica, quindi il secondo per il loop deve inizializzare il proprio contatore e cancellare l'array dei risultati. Mostra che "isset || null" è più veloce. codepad.org/Np6oPvgS
KyleWpppd,

3
@Tomalak, isset($array[$i]) || $array[$i] === nullnon ha senso perché tornerà trueper ogni caso. Non sarai mai falso isset($array[$i]) || $array[$i] === nullindipendentemente dagli input.
Pacerier

10

Volevo aggiungere i miei 2 centesimi a questa domanda, poiché mi mancava una via di mezzo.

Come già detto isset(), valuterà il valore della chiave in modo che ritorni falsese quel valore è nulldove array_key_exists()controllerà solo se la chiave esiste nell'array.


Ho eseguito un semplice benchmark utilizzando PHP 7, i risultati mostrati sono il tempo impiegato per terminare l'iterazione:

$a = [null, true];

isset($a[0])                            # 0.3258841  - false
isset($a[1])                            # 0.28261614 - true
isset($a[2])                            # 0.26198816 - false

array_key_exists(0, $a)                 # 0.46202087 - true
array_key_exists(1, $a)                 # 0.43063688 - true
array_key_exists(2, $a)                 # 0.37593913 - false

isset($a[0]) || array_key_exists(0, $a) # 0.66342998 - true
isset($a[1]) || array_key_exists(1, $a) # 0.28389215 - true
isset($a[2]) || array_key_exists(2, $a) # 0.55677581 - false

array_key_isset(0, $a)                  # 1.17933798 - true
array_key_isset(1, $a)                  # 0.70253706 - true
array_key_isset(2, $a)                  # 1.01110005 - false

Ho aggiunto i risultati di questa funzione personalizzata anche con questo benchmark per il completamento:

function array_key_isset($k, $a){
    return isset($a[$k]) || array_key_exists($k, $a);
}

Come visto e già detto isset()è il metodo più veloce ma può restituire false se il valore è null. Questo potrebbe dare risultati indesiderati e di solito si dovrebbe usarearray_key_exists() questo caso.

Tuttavia c'è una via d'uscita e che sta usando isset() || array_key_exists(). Questo codice utilizza generalmente la funzione più veloce isset()e se isset() restituisce solo false, utilizzare array_key_exists()per convalidare. Indicato nella tabella sopra, è veloce come una semplice chiamata isset().

Sì, scrivere e racchiuderlo in una funzione è un po 'più lento ma molto più semplice. Se questo è necessario per prestazioni, controllo di big data, ecc., Scriverlo per intero, altrimenti è un utilizzo di 1 volta che un sovraccarico molto piccolo in funzione array_key_isset()è trascurabile.


7

Con Php 7 offre la possibilità di utilizzare l' operatore Null Coalescing .

L'operatore null coalescing (??) è stato aggiunto come zucchero sintattico per il caso comune di necessità di utilizzare un ternario insieme a isset (). Restituisce il suo primo operando se esiste e non è NULL; altrimenti restituisce il suo secondo operando.

Quindi ora puoi assegnare un valore predefinito nel caso in cui il valore sia nullo o se la chiave non esiste:

$var = $array[$key] ?? 'default value'

6

c'è una differenza da php.net leggerai:

isset () non restituisce VERO per le chiavi dell'array che corrispondono a un valore NULL, mentre lo fa array_key_exists ().

Un test molto informale dimostra array_key_exists()di essere circa 2,5 volte più lento diisset()


3

Combinando isset()e is_null()dare la migliore prestazione contro altre funzioni come: array_key_exists(), isset(), isset()+ array_key_exists(), is_null(), isset()+is_null() , l'unico problema qui è la funzione non solo restituire false se la chiave non esiste, ma anche la chiave di esistere e ha un valore nullo.

Script di benchmark:

<?php
  $a = array('a' => 4, 'e' => null)

  $s = microtime(true); 
  for($i=0; $i<=100000; $i++) { 
    $t = (isset($a['a'])) && (is_null($a['a'])); //true 
    $t = (isset($a['f'])) && (is_null($a['f'])); //false
    $t = (isset($a['e'])) && (is_null($a['e']));; //false 
  } 

  $e = microtime(true); 
  echo 'isset() + is_null() : ' , ($e-$s)."<br><br>";
?>

Credito : http://www.zomeoff.com/php-fast-way-to-determine-a-key-elements-existance-in-an-array/


1

Quanto a "più veloce": provalo (il mio denaro è attivo array_key_exists() , ma non posso provarlo ora).

Quanto a "più chiaro nell'intento": array_key_exists()


3
isset () è in realtà significativamente più veloce se non ti interessa il comportamento nullo (vedi randombenchmarks.com/?p=29 ).
Matt Kantor,

0

Ovviamente il secondo esempio è più chiaro nelle intenzioni, non c'è dubbio. Per capire cosa fa l'esempio n. 1, devi avere familiarità con le idiosincrasie di inizializzazione variabile di PHP - e poi scoprirai che funziona diversamente per valori nulli, e così via.

Per quanto riguarda ciò che è più veloce - non intendo speculare - esegui un ciclo stretto alcune centinaia di migliaia di volte sulla tua versione di PHP e lo scoprirai :)


-2

Il tuo codice, isset($array[$i]) || $array[$i] === nullrestituirà true in ogni caso, anche se la chiave non esiste (e genera un avviso sull'indice indefinito). Per la migliore performance, quello che vorresti èif (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}


1
L'unica volta $array[$i] === nullche verrà eseguita è quando $ i esiste nell'array e ha il valore NULL ..
Niclas Larsson
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.