Blog what I write

Optimizando PHP

post - - 7 replies -

Aquí expongo algunas cuestiones que pueden ayudarnos a optimizar nuestros scripts en PHP. Sería bonito que hubiera comentarios aportando mas información acerca de este interesante tema.

VARIABLES

  • Una buena práctica es inicializar las variables antes de usarlas (cuestión obligatoria en otros muchos lenguajes). Esta tarea de inicialización agilizará nuestros scripts.
  • Los incrementos/decrementos de las variables son más rápidos si se tratan de variables locales que globales. Y diría más, todos los aspectos globales trabajan bajo un ámbito mayor, por lo tanto es lógico pensar que se manejen algo mas lentos.
  • Las operaciones sobre las propiedades de un objeto $this->num++ son mas lentas que las realizadas en variables locales, (al menos en versiones anteriores a la 5).
  • Pablo -de weBlog “UnLugar”- nos deja un interesante estudio de optimización sobre la definición de variables, constantes y matrices.

BUCLES

  • En las estructuras iterativas (bucles): for, while, etc. debemos (si es posible) tratar de hacer pocas llamadas a funciones. Y más aún a consultas SQL.
    En muchos casos podremos realizar esas consultas SQL de forma mas global (y unitaria) justo como paso previo al bucle, para que dentro de este nos dediquemos a recorrer la matriz con los datos ya extraídos de la SQL.
  • No debemos incluir funciones en las definiciones de bucles. Por ejemplo:
    for($x=0; $x<=count($var); $x++);

    En este bucle estamos provocando que se analice la función count() por cada iteración. Sería más sencillo y eficiente esto:

    $num = count($var);
    for($x=0; $x<= $num; $x++);
  • Para la lectura de una matriz, parece ser más rápido el empleo del clásico for que foreach o while, siendo este último el más lento. Esto parece tener mucha lógica si nos fijamos en la propia estructura y definición de cada bucle.

FUNCIONES

  • El paso de parámetros a funciones conlleva su tiempo, no se debe uno exceder en el número de parámetros. Es preferible pasar como parámetro un array con sus ocho valores, que pasar uno a uno en cada variable.
  • Para saber si una variable esta definida es más rápido usar isset() que cualquier otro tipo de funciones. También es muy rápido el uso empty() (mi preferido).
  • Sería lógico pensar que if(empty(valor)) es más eficiente que su contrario if(!empty($var)), pero la diferencia es despreciable.
  • En el trabajo con datos aleatorios, es más rápida mt_rand() que rand() y mt_srand(), que srand().
  • Se dice que sizeof() cuenta los elementos más rápido que count(), aunque también se comenta que esta diferencia es inapreciable. Yo personalmente me quedo con count(), si nos fijamos en el manual oficial, nos dice que sizeof() es un alias de count(), si esto fuera así PHP haría el paso más en sizeof(), convirtiendo a count() en más rápida. Por otro lado parece que toda la documentación y comentarios gira entorno a count().
  • Parece ser que echo() es más rápido que print(), pero la diferencia parece ser demasiado pequeña. No obstante desde un comienzo le he cogido apego a echo() y solamente uso printf en determinados casos de formateado de texto.
  • Tengamos en cuenta que no se evalúa el contenido de las comillas simples, por el contrario las comillas dobles sin son evaluadas en busca de variables. Esto hace que sea más rápido el uso de las simples en caso de no existir variables incrustadas en la cadena a mostrar.
  • Es más rápida la apertura y cierre de cadenas para mostrar variables que incrustarlas dentro de un string.
    Mejor:
    echo ‘hola, me llamo: ’.$name;

    Peor:

    echo “hola me llamo: $name”;
  • Las funciones implode(), y explode() son bastante rápidas. En concreto explode() es más rápida que split().
  • Los include_once() y require_once(), son más lentos que include() y require(). Si puedes ser ordenado y evitar lo máximo posible sus llamadas, estarás ganando en velocidad, puesto que “_once” realiza dos pasos: el primero de ellos verificar si el fichero ha sido incluido y el segundo incluirlo (en muchos casos de forma innecesaria).
  • Reducir los accesos al disco duro, cuanto menos accedemos a el mejor. Cuando se comienza con este lenguaje es normal que uno no se preocupe por estas cosas y use funciones file_exists(), filesize(), readdir(), etc. de forma muy alegre y asidua.
  • Reducir los accesos a la base de datos, y aunque parezca evidente, SOLO consultar aquellos datos que vamos a emplear en el script.

METODOLOGIA

  • Programación estructurada VS Orientada a objetos
    Pienso que la programación estructurada se procesa en menor tiempo que la orientada a objetos. Otras cuestiones son la reutilización, legibilidad, y etc beneficios de la orientada a objetos. Bajo el motor de Zend 2.0, esto parece cambiar mucho y ser realmente eficiente trabajando con POO.
    Mi visión personal es que este lenguaje fue concebido pensando en todo momento en C (lo lleva en las entrañas) y esto no me parece un punto negativo, sino más bien positivo.
    Creo que la mejor opción es emplear POO, pero sin excesos de clasitis, dejando también un hueco para la programación estructurada.
  • Parecerá tonto, pero cabe decir que no se debe inicializar nada, que no vaya a ser usado. Tampoco se deben programar: funciones, clases, objetos, etc. que no sean empleados durante el transcurso del script activo. Mas grave sería incluir ficheros (include/require) sin ser usados o que contengan algunas funciones que tampoco vayan a utilizarse.
  • La salida de errores hacen lentos nuestros script (muy lógico) pero más aún si los escondemos con “@”.
  • La eliminación de comentarios NO acelera nuestro código, es un mito. En tal caso si que puede disminuir el peso del fichero, pero únicamente eso.
  • Incrustar HTML es más lento que su salida directa. No obstante esto es un “arma” de doble filo, puesto que la apertura y cierre de “<?php – ?>” también conlleva su retardo. Por tanto no se debe abrir y cerrar con demasiada frecuencia, siendo lo mejor evaluar cada caso y ver que es lo más lógico.
  • El trabajo con números es muchísimo más rápido que el de cadenas. Cuestión más que lógica, en informática. Por tanto es preferible usar matrices con índices numéricos, operaciones con números, bucles, condicionales, etc. Esta cuestión se puede extrapolar a otros campos, observemos como cualquier gestor de base de datos trabaja mucho más rápido con una tabla de índices numéricos que una que emplee cadenas de caracteres (aunque sean muy cortas).
  • No reinventar la rueda si la nueva rueda no es muchísimo mejor que la ya inventada. También sería conveniente que antes de realizar cualquier algoritmo consultásemos siempre, si ya existe alguna función a tal efecto.
  • Optimización no es solo velocidad sino peso de la aplicación. Cuanto mayor sea el tamaño de la aplicación menos eficiente será. Se deben buscar algoritmos breves y concisos, que reduzcan el peso/velocidad y con ello también el consumo de memoria.
  • Siempre que fuera posible se debería huir de la complejidad innecesaria, lo simple será más eficiente y más rápido en procesamiento. Y en muchos casos podemos hacer lo de simple algo muy inteligente.
  • EXPERIENCIA, es normal (y lógico) que un programador con poca experiencia desarrolle algoritmos mas pesados y de poca eficiencia. Como cualquier otro lenguaje tiene una curva de aprendizaje y una vez conseguido, la experiencia es la que otorga al programador la capacidad para crear mejores y más eficientes algoritmos.
  • Se me olvido poner un enlace muy interesante: http://www.php.lt/benchmark/phpbench.php

  • Lokycss

    Otra opción para no añadir funciones dentro de un bucle es ésta:

    for($x=0, $num = count($var); $x

  • Hola Lokycss.

    Interesante…
    Gracias por tu aportación 😉

  • Pingback: Links 2007-08-28()

  • enhorabuena por el artículo, está genial para desempolvar mis conocimientos de php. Seguiré atento al blog 😀

  • Muchas gracias fesja 😉

  • Luketi

    Muy bueno el aporte!
    gracias por compartir 😉