2011-04-15 17 views
7

Estaba revisando las respuestas a diferentes preguntas para obtener más información. Vi un answer que dice que es una mala práctica en php para escribir

 
for($i=0;$i<count($array);$i++) 

Dice que llamar a la función recuento en el bucle reduce la velocidad del código. La discusión en los comentarios sobre esta pregunta no fue clara. Quiero saber por qué no es una buena práctica. ¿Cuál debería ser la forma alternativa de hacer esto?

Respuesta

8

Usted debe hacer esto en su lugar:

$count = count($array); 
for($i=0;$i<$count;$i++)... 

La razón para hacer esto es porque si se pone el count($array) dentro del bucle entonces la función de recuento tendría que ser llamado para cada iteración que ralentiza la velocidad.

Sin embargo, si pone el recuento en una variable, es un número estático que no tendrá que volver a calcularse cada vez.

+0

pero ¿cuál es el motivo? –

+0

@Awais agregué el motivo – Neal

4

Para cada iteración, PHP es la comprobación de que parte del bucle (el condición) para ver si se debe mantener en bucle, y cada vez que se comprueba que, es el cálculo de la longitud de la matriz.

Una manera fácil de caché que el valor es ...

for($i=0,$count=count($array);$i<$count;$i++) { ... } 

Probablemente no es necesario en pequeños bucles, pero podría hacer una gran diferencia cuando se repite a través de miles de artículos, y depende de lo la llamada de función está en la condición (y cómo determina su valor de retorno).

También es por eso que debe usar foreach() { ... } si puede, utiliza un iterador en una copia de la matriz para recorrer el conjunto y no tiene que preocuparse por almacenar en caché la condición del bucle.

+0

¿Quiere decir que el bucle foreach mantiene la copia de la matriz? Lo siento, no lo entendí. –

+1

@Awais Sí, antes de iterar sobre él, crea una copia, lo restablece y avanza su puntero en lugar del original. – alex

+0

bueno, pero si tenemos una matriz muy grande, ¿es una solución factible que un bucle tenga una copia y una matriz original? –

1

No es una buena práctica porque, como está escrito, se llamará a count($array) cada vez que pase el ciclo. Suponiendo que no va a cambiar el tamaño de la matriz dentro del bucle (que a su vez sería una idea horrible), esta función siempre devolverá el mismo valor, y llamarlo repetidamente es redundante.

Para bucles cortos, la diferencia probablemente no será notable, pero aún así es mejor llamar a la función una vez y usar el valor calculado en el bucle.

3

Escuché de una base de datos en una consulta médica que cometió exactamente este error con un software. Fue probado con aproximadamente 100 registros, todo funcionó bien. En unos pocos meses, estaba lidiando con millones de registros y era totalmente inutilizable, demorando minutos en cargar los resultados. El código fue reemplazado según las respuestas anteriores, y funcionó perfectamente.

Para pensarlo de otra manera, un servidor dedicado bastante poderoso que no hace mucho más tardará aproximadamente 1 nanosegundo en contar ($ array). Si tenía 100 bucles for, cada uno contando 1,000 filas, entonces eso es solo 0.0001 de segundo.

Sin embargo, eso es 100.000 cálculos para CADA carga de página. Escala hasta 1,000,000 de usuarios (¿y quién no quiere tener 1 millón de usuarios?) ... haciendo cargas de 10 páginas y ahora tienes 1,000,000,000,000 (1 billón) de cálculos. Eso va a poner mucha carga en el servidor. Son 1000 segundos (aproximadamente 16.5 minutos) que su procesador pasa ejecutando ese código.

Ahora aumente el tiempo que le lleva a la máquina procesar el código, el número de elementos en las matrices y el número de bucles for en el código ... está hablando de literalmente muchos billones de procesos y muchas horas del tiempo de procesamiento que se puede evitar simplemente almacenando primero el resultado en una variable.

+0

+1 para estadísticas .... –

Cuestiones relacionadas