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.