Esta pregunta es solo para mí, ya que siempre me gusta escribir código optimizado que pueda ejecutarse también en servidores lentos y baratos (o servidores con MUCHO tráfico)
Miré a mi alrededor y no pude encontrar una respuesta. Me preguntaba qué es más rápido entre esos dos ejemplos teniendo en cuenta que las claves de la matriz en mi caso no son importantes (pseudocódigo, naturalmente):
<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
if(!in_array($new_val, $a){
$a[] = $new_val;
//do other stuff
}
}
?>
<?php
$a = array();
while($new_val = 'get over 100k email addresses already lowercased'){
if(!isset($a[$new_val]){
$a[$new_val] = true;
//do other stuff
}
}
?>
Como el punto de la pregunta no es la colisión de la matriz, me gustaría agregar que si tiene miedo de colisionar las inserciones $a[$new_value]
, puede usar $a[md5($new_value)]
. aún puede causar colisiones, pero evitaría un posible ataque DoS al leer un archivo proporcionado por el usuario ( http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html )
fuente
Respuestas:
Las respuestas hasta ahora son acertadas. Usar
isset
en este caso es más rápido porquein_array
debe verificar cada valor hasta encontrar una coincidencia.in_array
función incorporada.Estos se pueden demostrar usando una matriz con valores (10,000 en la prueba a continuación), lo
in_array
que obliga a realizar más búsquedas.Esto se basa en el punto de referencia de Jason al completar algunos valores aleatorios y, ocasionalmente, encontrar un valor que exista en la matriz. Todo al azar, así que ten cuidado con los tiempos que fluctúan.
fuente
isset()
es más rápido.Si bien debería ser obvio,
isset()
solo prueba un valor único. Considerandoin_array()
que iterará sobre toda la matriz, probando el valor de cada elemento.La evaluación comparativa aproximada es bastante fácil de usar
microtime()
.Resultados:
Nota: Los resultados fueron similares independientemente de si existían o no.
Código:
Recursos adicionales
Te animo a que también mires:
fuente
microtime()
otras herramientas. Increíblemente valioso.in_array
función versus usar la funciónisset
integrada. Esto sería mejor con una matriz que contenga un montón de claves aleatorias y ocasionalmente busque una clave / valor existente.while
yforeach
que en cada actualización obtenía diferentes "ganadores". siempre depende de demasiadas variables del servidor, y lo mejor es iterar una gran cantidad de veces en diferentes momentos y obtener el que gane con más frecuencia, o simplemente saber lo que sucede en segundo plano y saber que será el ganador final pase lo queisset()
, ¿qué le hace pensar que pasarla una matriz más grande la haría más rápida ?El uso
isset()
aprovecha una búsqueda más rápida porque usa una tabla hash , evitando la necesidad deO(n)
búsquedas.La clave se hash primero usando la función hash djb para determinar el grupo de claves con hash similar en
O(1)
. Luego, se busca en el depósito de forma iterativa hasta que se encuentra la clave exactaO(n)
.Salvo cualquier colisión de hash intencionada , este enfoque produce un rendimiento mucho mejor que
in_array()
.Tenga en cuenta que cuando se usa
isset()
de la manera que ha mostrado, pasar los valores finales a otra función requiere usararray_keys()
para crear una nueva matriz. Se puede comprometer la memoria almacenando los datos tanto en las claves como en los valores.Actualizar
Una buena forma de ver cómo las decisiones de diseño de su código afectan el rendimiento en tiempo de ejecución, puede consultar la versión compilada de su script:
echo isset($arr[123])
echo in_array(123, $arr)
No solo
in_array()
usa unaO(n)
búsqueda relativamente ineficiente , también necesita ser llamada como una función (DO_FCALL
) mientras queisset()
usa un solo código de operación (ZEND_ISSET_ISEMPTY_DIM_OBJ
) para esto.fuente
El segundo sería más rápido, ya que solo busca esa clave de matriz específica y no necesita iterar sobre toda la matriz hasta que se encuentre (mirará cada elemento de la matriz si no se encuentra)
fuente
isset()
si no se encuentra?