Credit image

¿Te gusta el diseño web? ¡Echa un vistazo a la documentación de LenguajeCSS.com!

Funciones PHP: Optimizar código

Los programadores (sobre todo en la fase de aprendizaje) 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. Por ejemplo, en un blog, optimizar un script PHP de una sección concreta no repercute especialmente en el rendimiento. Sin embargo, optimizar un script PHP que se ejecuta siempre (por ejemplo, el menú o la zona del logotipo superior) puede ayudar a reducir el uso de recursos.

NOTA: No hay que obsesionarse con la optimización a estos niveles. Siempre es bueno tener estos consejos en cuenta (sobretodo para scripts que se ejecutan muchísimas veces). No obstante, no hay que caer en el antipatrón de la optimización obsesiva.

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, sobre todo si contienen mucha información (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 el primero 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.
  • 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.

Escrito por Manz, el , en programacion. Comentarios recibidos: 18.

18 comentarios de lectores
Abel
Abel
1

El artículo parece más bien enfocado a la optimización de la memoria y la velocidad de respuesta del servidor. Y con esa misma lógica yo añadiría el buscar siempre las construcciones del lenguaje que nos eviten el uso de funciones. Por ejemplo, echo es más rápido que print porque es una construcción del lenguaje y no una función. Lo mismo pasa con la construcción isset que a diferencia de las funciones is_int, is_string, empty etc. es más rápido. Ahora siguiendo con la optimización de código, me parece bueno mencionar el uso del operador ternario en lugar de un simple if/else.

Alejandro Torres
Alejandro Torres
2

También agregaría el uso de comillas simples en vez de comillas dobles, ya que en comillas dobles el servidor tarda un poquito mas por que busca variables dentro de esta :-P Un saludo ;-)

pedro
pedro
3

Una pregunta: Pero es sólo evitar usar funciones definidas o también evitar crear funciones? Ejemplo: function algo();

  • 2
Aldope drogar cia
Aldope drogar cia
4

Yo solo se que no se nada ! y bue !

  • -1
Manz
Manz
5

Pedro la cuestión no es llegar a un punto paranoico con respecto a la optimización, sino seguir unas pautas lógicas y sencillas. Con respecto a tu pregunta, el tema es no crear funciones que hagan algo que ya está creado (busca en PHP o en la Chuleta PHP si existe una función que haga lo que quieres).

Angel
Angel
6

Diferiría en la cuestión que las comillas simples son más eficientes. Es cierto que a mi me gustan más y tener todo concatenado pero es preferible por ejemplo tener echo "hola $nombre" que echo 'hola '.$nombre esto sencillamente por la razon que no podemos incluir $ en las apostrofes sin tener que concatenar... en las comillas dobles sí que se puede.

Manz
Manz
7

Hola Angel, En realidad tienes parte de razón. En el artículo me he basado en la prueba que hicieron en phpbench. Sin embargo, creo recordar haber leído alguna vez que utilizar las comillas simples frente a las comillas dobles, en algunos casos, como por ejemplo, varias concatenaciones seguidas, serían más costosas que usar las comillas dobles con sus variables respectivas. Pero esto ya no lo puedo asegurar.

inyaka
inyaka
8

me sucedio en el trabajo, se qu e para algunos debe ser muy obvio, pero para quien no sabe puede ser util, ademas del php, cuando se hacen consultas, sobre todo cruzadas (con algún JOIN) es importante para el rendimiento en la DB indicar los indices de las tablas, esto acelera muchísimo la DB PD. mysql rulez

  • 1
tru3n0
tru3n0
9

Muchas gracias por los tips!

dago
dago
10

el preocuparnos demaciado por la optimizacion temprana sin ocuparnos en la funcionalidad es uno de los peores males de la ingenieria de software, debemos tener en cuenta que el lenguaje sigue evolucionando y optimizandose, y eso sin tener en cuenta el soporte operativo sobre los cuales corren los servicios los cuales cada vez son mas poderosos, deberiamos luego ocuparnos por el diseño y la funcionalidad de nuestras aplicaciones antes de pensar en optimizarlos para no desperdiciar una milesima de segundo.

Jonathan
Jonathan
11

Muy buien articulo, aunque me quedo una duda. A mi siempre me han recalcado que switch es mas rapido que los if else, especialmente cuando los if elseif else son extensos... quede con esa duda.

  • 1
Succubatrón
Succubatrón
12

¡He salvado a un gatito!

  • -2
Emiliano
Emiliano
13

Si no estoy leyendo mal el Manual de PHP (http://es.php.net/manual/es/language.operators.comparison.php) sería mas eficiente usar el operador == en contraposición con === como dice el artículo, ya que es al revés de como dice el artículo, el operador === es el que compara si las variables son del mismo tipo y valor (idénticas).

Manz
Manz
14

@Emiliano: Tienes toda la razón. El concepto es correcto, pero hay una errata. El operador === es el que realiza la comprobación de tipos. Lo he corregido. Gracias.

Quim
Quim
15

Hay un punto que puede confundir a la gente, lo voy a aclarar... IF/ELSE es siempre mas rapido que SWITCH/CASE, cierto... Pero a la que usamos IF/ELSE IF es bastante mas lento i se recomienda entonces el SWITCH/CASE. Aquí está demostrado. Unicamente será mas rapido el IF/ELSE IF frente al SWITCH/CASE si usamos el comparador (===), si estamos forzados a usar == en un IF/ELSE IF es mas optimo SWITCH CASE!! :)

  • 1
Ivan
Ivan
16

y sin embargo en otros lados dicen que sizeof es mas rapido que count, que require_once e include_once ya no son lentos comparados con require e include, claro hablando de la ultima version de php a 5.3 total nadie se pone de acuerdo

emilio
emilio
17

Escuche varias veces que el operador ? en c es mas rapido que un if/else. Me pregunto si esto sera tambien asi en php.

osvaldo
osvaldo
18

Muchas gracias me sirvió mucho para optimizar mi código, y aprender más...

Publica tu opinión

Si lo deseas, puedes utilizar el siguiente formulario para publicar tu opinión o responder a alguna de las existentes:

Previsualización

Aquí se previsualizará su comentario. Revise que sea correcto antes de publicarlo.