Optimizar código PHP

Los programadores (sobre todo los que estamos aprendiendo) solemos preocuparnos poco de la optimización de código cuando realizamos un programa. A priori, le damos importancia a dos factores:

  • Funcionalidad: La más intuitiva de todas. Que el programa que estamos realizando, haga lo que buscamos.
  • Brevedad: Buscamos que el programa ocupe lo menos posible.

Otros factores como rapidez, comprensión del código, optimización, documentación… no son evaluados como criterios primarios. Sin embargo, son muy importantes .

En la programación web (más si cabe) uno de los criterios más importantes es la optimización, ya que disponemos de un servidor con recursos limitados. Si conseguimos que nuestro código sea más eficiente, dispondremos de más capacidad en nuestro servidor (menos carga).

Esto es especialmente importante cuando tenemos muchas visitas diarias: optimizar un script PHP de un artículo no repercute especialmente, en cambio, optimizar un script PHP que se ejecuta siempre (por ejemplo, el sidebar) mejora ampliamente la eficiencia de nuestro código.

En PHP Benchmark hacen algunas pruebas de eficiencia con respecto a funciones similares de PHP. A continuación voy a hacer un breve repaso, con algunos añadidos:

  • Usar HTML ante PHP: Si necesitas escribir HTML hazlo directamente sin utilizar echo o print . Usa PHP para imprimir información sólo cuando sea necesario.

  • Variables: Favorece siempre que puedas el uso de variables estáticas. No utilices variables que no necesites (ocupan memoria). Evita las variables globales en la medida de lo posible. Usa constantes.
  • Unset: Utiliza la función unset para destruir variables y liberar memoria, sobre todo con arrays o variables extensas. PHP usa un Garbage Collector, pero en mitad de un script puedes usarlo para maximizar la memoria disponible (útil en servidores limitados).
  • Bucles: Revisa bien los bucles en tus programas, si no es necesario un bucle, evitalo. Si puedes ahorrarte ciclos, hazlo. Comprueba la condición de parada y nunca uses funciones en ella (vuelca en una variable antes del bucle). En términos de velocidad un do..while es más rápido que un while, que a su vez es más rápido que un for .
  • Inclusiones: Organiza bien tu código y evita en lo posible el uso de funciones como include_once() y require_once(). Estas funciones son muy utiles para comprobar si un script ya ha sido procesado, pero son muy costosas. En su lugar utiliza include() y require().
  • Supresión de errores @: Al colocar una @ antes de una función evitamos que se muestre un posible mensaje de error. Muy útil, pero muy costoso. Es preferible utilizar un funcion() or … .
  • Random: Si queremos generar valores aleatorios con la función rand(), es recomendable utilizar la familia de funciones mt_rand(). Esta función utiliza un algoritmo de Mersenne Twister mucho más eficiente y rápido.
  • Uso de comillas en PHP: Las comillas simples interpretan literales, sin embargo, las comillas dobles además interpolan el valor de variables. Da siempre preferencia a las comillas simples y nunca escribas símbolos de dolar sin escapar ( $ ) en comillas dobles, ralentiza mucho la ejecución.
  • Comprobar si existen variables: Siempre se debería utilizar una función para comprobar si existe una variable. Entre las funciones isset(), empty() y is_array(), la primera es la más rápida y eficiente.
  • Operador ===: En las comparaciones, la diferencia del operador === con el operador == es que este último hace una comprobación de tipos de variables antes. Si estás seguro de que son del mismo tipo, utiliza el primero.
  • Memoria y velocidad: Utiliza memory_get_usage() y microtime() para comprobar la velocidad y la memoria que consume tu código.
  • Comparaciones: Los if / else son siempre más rápidos que los switch / case.
  • Las siguientes funciones son alias de las de su derecha. Utilizar la función de la izquierda es mucho más lento que usar la de la derecha:
    • chop -> rtrim
    • close -> closedir
    • die -> exit
    • dir -> getdir
    • diskfreespace -> disk_free_space
    • fputs -> fwrite
    • ini_alter -> ini_set
    • is_writeable -> is_writable
    • join -> implode
    • pos -> current
    • rewind -> rewinddir
    • strchr -> strstr
    • sizeof -> count

    Curiosamente, fputs, a pesar de ser un alias, se comenta que es más rápida que fwrite.

  • Incrementos: Cuando incrementamos una variable del modo $i++ es más lento que si lo hacemos ++$i . La diferencia es que la primera forma primero usa su valor y luego lo incrementa, en cambio, la segunda primero la incrementa y luego la usa. La segunda forma es más rápida, puesto que utiliza 3 opcodes, en lugar de los 4 opcodes de la primera. Usarla cuando sea posible.
  • Imprimiendo textos: La función echo es más rápida que la función print, además de otras diferencias.
  • Expresiones regulares: El uso de regexp es muy contradictorio. Como ventajas tenemos que usan muy poca de memoria, muy potentes y ahorran mucho código. Como desventajas son muy lentas, muy difíciles para novatos o personas que no conozcan teoría de autómatas y lenguajes formales. Personalmente, aconsejo evitarlas a no ser que sean muy necesarias. Por ejemplo, la expresión regular preg_match(“![0-9]+!”, $foo); reconoce cualquier cadena que sea un número, esto es mucho mas eficiente usando la función ctype_digit($foo);. Las funciones strcasecmp(), strpbrk() y stripos() pueden ayudar mucho.
  • Reporte de errores: Utiliza E_STRICT como nivel de error para hacer debug en tu código PHP. Revisando los logs podrás ver todos los avisos de posibles errores con un nivel máximo.
  • Separaciones: split() permite utilizar expresiones regulares, mientras que explode() no. Intenta utilizar explode siempre antes que la función split.

Fuentes: 12 PHP tricks / PHP benchmarks / 7 tips for PHP / More PHP tips.

Deja un comentario