¿Qué es más rápido y mejor para determinar si existe una clave de matriz en PHP?

157

Considere estos 2 ejemplos ...

$key = 'jim';

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

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

Estoy interesado en saber si alguno de estos es mejor. Siempre he usado el primero, pero he visto a muchas personas usar el segundo ejemplo en este sitio.

Entonces, ¿cuál es mejor? ¿Más rápido? Intento más claro?

alex
fuente
No he ejecutado ningún punto de referencia, no. ¿Debo tener antes de preguntar?
alex
44
issetnunca se comportará exactamente como array_key_exists, el ejemplo de código que supuestamente hace que se comporte de manera idéntica arroja un Aviso si la clave no existe.
deceze
¿Qué hay de in_array? maettig.com/1397246220
DanMan
1
@DanMan, in_arrayes O(n)porque verifica los valores, no las claves. Casi siempre serán más lentos a menos que nsea ​​extremadamente pequeño.
Pacerier
¿Por qué no $array[$key] === null?
Pacerier

Respuestas:

237

isset()es más rápido, pero no es lo mismo que array_key_exists().

array_key_exists()simplemente verifica si la clave existe, incluso si el valor es NULL.

Mientras isset()que volverá falsesi la clave existe y el valor es NULL.

Richard Levasseur
fuente
66
¿Tiene recursos específicos que afirman que isset es más rápido?
Francesco Pasa
@Francesco Pasa Solo piénsalo un poco. issetno es una función de búsqueda de matriz, solo verifica la presencia de una variable en la tabla de símbolos y no iterará sobre la matriz. array_key_existspor otro lado iterará / buscará las claves en la primera dimensión de la matriz especificada.
Lluvia
@Rain Estoy bastante seguro de array_key_exists()que solo verificará si la clave está en la matriz, lo que significa que no hará una búsqueda ya que es una tabla hash.
Francesco Pasa
@FrancescoPasa Bueno, "buscar las claves" es lo que dice la documentación de PHP. Aparte de eso, no puedo decir si "buscar" para ellos significa algo completamente diferente de lo que significa para mí.
Lluvia
32

Si está interesado en algunas pruebas que he hecho recientemente:

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

Resumen:

| 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%
Populus
fuente
IMPORTANTE: se descubrió que el tiempo de arrayKeyExists era muy incorrecto; estaba comprobando el valor, no la clave, siga ese enlace para el tiempo revisado en 7.1, que es mucho mejor. (También sería mejor en versiones anteriores de php, si Populus rehiciera esa prueba)
ToolmakerSteve
19

Bueno, la principal diferencia es que isset()no volverá truepara las claves de matriz que corresponden a un valor nulo, mientras que array_key_exists()sí.

Ejecutar un pequeño punto de referencia muestra que isset()es más rápido, pero puede que no sea del todo preciso.

CMS
fuente
1
¿Puede ejecutar el punto de referencia nuevamente con el "correcto (isset ($ array [$ i]) || $ array [$ i] === null)"?
Tomalak
Ah, ¿y publicaría una indicación de cuánta diferencia de rendimiento muestran las dos variantes? ¡Gracias!
Tomalak
1
@Tomalak, ejecuté el ejemplo que sugirió, y dice que array_key_exists () es más rápido que isset () con el || operador. codepad.org/5qyvS93x
alex
1
Arriba de la muerte ... pero también volví a ejecutar el punto de referencia, e hice un ajuste para que el segundo bucle for deba inicializar su propio contador y borrar la matriz de resultados. Muestra que "isset || null" es más rápido. codepad.org/Np6oPvgS
KyleWpppd
3
@Tomalak, isset($array[$i]) || $array[$i] === nullno tiene sentido porque regresará truepara cada caso. Nunca obtendrá falso de isset($array[$i]) || $array[$i] === nullindependientemente de las entradas.
Pacerier
10

Quería agregar mis 2 centavos en esta pregunta, ya que me faltaba una salida intermedia.

Como ya se dijo isset(), evaluará el valor de la clave para que regrese falsesi ese valor es nulldonde array_key_exists()solo verificará si la clave existe en la matriz.


Ejecuté un punto de referencia simple usando PHP 7, los resultados mostrados son el tiempo que tardó en finalizar la iteración:

$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

También agregué los resultados de esta función personalizada con este punto de referencia para completar:

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

Como se ve y ya se dijo, isset()es el método más rápido, pero puede devolver falso si el valor es null. Esto podría dar resultados no deseados y, por lo general, uno debe usar array_key_exists()si ese es el caso.

Sin embargo, hay una salida intermedia y que está utilizando isset() || array_key_exists(). Este código generalmente usa la función más rápida isset()y si isset() devuelve falso solo se usa array_key_exists()para validar. Se muestra en la tabla de arriba, es tan rápido como simplemente llamar isset().

Sí, es un poco más escribir y envolverlo en una función es más lento pero mucho más fácil. Si necesita esto para el rendimiento, la verificación de datos grandes, etc., escríbalo completo; de lo contrario, si es un uso de 1 vez, la sobrecarga muy pequeña en la función array_key_isset()es insignificante.

Xorifelse
fuente
7

Con Php 7 ofrece la posibilidad de utilizar el Operador de fusión nula .

El operador de fusión nulo (??) se ha agregado como azúcar sintáctico para el caso común de necesitar usar un ternario junto con isset (). Devuelve su primer operando si existe y no es NULL; de lo contrario, devuelve su segundo operando.

Entonces ahora puede asignar un valor predeterminado en caso de que el valor sea nulo o si la clave no existe:

$var = $array[$key] ?? 'default value'
Juan
fuente
6

hay una diferencia de php.net que leerás:

isset () no devuelve VERDADERO para las claves de matriz que corresponden a un valor NULL, mientras que array_key_exists () sí.

Una prueba muy informal muestra array_key_exists()que es aproximadamente 2.5 veces más lenta queisset()

Scott Evernden
fuente
3

La combinación isset()y is_null()dar el mejor rendimiento frente a otras funciones como: array_key_exists(), isset(), isset()+ array_key_exists(), is_null(), isset()+ is_null(), el único problema aquí es que la función no sólo devolverá false si no existe la clave, pero incluso la llave de existir y tiene un valor nulo.

Script de referencia:

<?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>";
?>

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

H Aßdøµ
fuente
1

En cuanto a "más rápido": Pruébelo (mi dinero está encendido array_key_exists(), pero no puedo probarlo ahora).

En cuanto a "más claro en la intención": array_key_exists()

Tomalak
fuente
3
isset () es en realidad significativamente más rápido si no le importa el comportamiento nulo (consulte randombenchmarks.com/?p=29 ).
Matt Kantor
0

Obviamente, el segundo ejemplo tiene una intención más clara, no hay duda al respecto. Para averiguar qué ejemplo # 1 hace, debe estar familiarizado con las idiosincrasias de inicialización variable de PHP, y luego descubrirá que funciona de manera diferente para valores nulos, y así sucesivamente.

En cuanto a cuál es más rápido, no tengo la intención de especular, ejecute cualquiera de los doscientos mil veces en su versión de PHP y lo descubrirá :)

Mihai Limbășan
fuente
-2

Su código, isset($array[$i]) || $array[$i] === nulldevolverá verdadero en todos los casos, incluso si la clave no existe (y generará un aviso de índice indefinido). Para obtener el mejor rendimiento, lo que desea esif (isset($array[$key]) || array_key_exists($key,$array)){doWhatIWant();}

Gator
fuente
1
El único momento en $array[$i] === nullque se ejecutará es cuando $ i existe en la matriz y tiene el valor NULL ..
Niclas Larsson