Contactos

Aceleración de programas PHP. La optimización de PHP es el sello distintivo del código profesional de eAccelerator: recargas de código PHP más rápidas

Al desarrollar proyectos grandes, surge gradualmente la cuestión de optimizar el código del proyecto: qué tan justificado está el consumo de memoria, cómo se puede aumentar la velocidad de ejecución del código php escrito. Al principio, muchos no piensan en la corrección y eficiencia del código escrito, escriben según el principio: funciona, y eso está bien. Aunque el intérprete PHP ejecuta el código PHP con bastante rapidez y existen muchos cuellos de botella que ralentizan la velocidad de ejecución del código fuera de PHP, la optimización del código PHP también es importante y la optimización del código debe aplicarse ya al comienzo de la codificación. proceso.

La mayoría de los scripts PHP hacen cosas simples. El comportamiento predeterminado del script es cargar una pequeña cantidad de información del usuario, obtener información de una base de datos o archivo, generar el HTML apropiado y enviar el resultado al cliente. Aquí, en primer lugar, debe comprender cuál debería ser exactamente el resultado de la optimización: velocidad, facilidad de escalado, reducción de la cantidad de recursos del servidor utilizados, reducción del tiempo de transferencia de datos o todo junto. En este último caso, es necesario no sólo encontrar todas las secciones críticas, sino también equilibrar su optimización.

Permítanme darles el ejemplo más simple, digamos que en un servidor con 100 MB de RAM libre hay dos scripts, cuyo resultado es el mismo. El primer script está optimizado para un rendimiento máximo, requiere 10 MB de memoria y recibe datos del archivo leyéndolo por completo, el segundo, para un consumo mínimo de memoria, requiere 5 MB de memoria y recibe datos del mismo archivo en partes. Como resultado de una solicitud, el primer script se ejecutará más rápido que el segundo, pero si hay más de diez solicitudes al mismo tiempo, es la velocidad del segundo script la que será más rápida. ¿Por qué está pasando esto? En el primer script, el cuello de botella es el uso de recursos de memoria, en el segundo, las características del sistema de E/S. Después de que el primer script consuma toda la RAM disponible, el sistema pasará a utilizar memoria virtual, mientras que el mismo sistema de E/S se convertirá en un cuello de botella adicional de este esquema.

Por supuesto, este ejemplo está muy simplificado y existen otros cuellos de botella además de la RAM, pero la idea principal es la siguiente: la optimización para un caso puede convertirse en un punto crítico en otro. En el ejemplo, como resultado de la optimización para un ligero aumento en la velocidad con cargas bajas, la velocidad de ejecución del script disminuyó significativamente con cargas más altas. Por lo tanto, para obtener un mayor rendimiento, es importante dedicar energía a optimizar áreas que realmente merecen atención.

No consideraré aquí la optimización del sistema operativo, la optimización de la configuración del servidor, etc., porque. la mayoría de los webmasters utilizan alojamiento y, en consecuencia, no podrán configurar todo por sí mismos. Aquí solo se considerará la optimización del código php. Cabe señalar que en cada caso algunos tipos de optimización serán útiles, otros supondrán una pérdida de tiempo y esfuerzo. A menudo, la utilidad de una mejora del código será insignificante. Quizás con el tiempo, los cambios internos en PHP hagan que las optimizaciones exitosas sean inútiles o incluso dañinas.

Las siguientes son las principales mejoras de rendimiento para PHP 5:

Pasos para optimizar el consumo de RAM:

  1. Análisis de los resultados de sus funciones. Antes de escribir una función, verifique si existe un equivalente estándar.
  2. Liberar memoria en caso de dejar de utilizar matrices u objetos grandes solo en el ámbito global (la memoria se liberará automáticamente en el ámbito local). Tenga en cuenta que la función desarmado() elimina la variable del alcance y, solo si no hay otras referencias al objeto, libera la memoria ocupada por el objeto. Asignar un valor a una variable nulo Siempre destruye el objeto y libera la memoria ocupada por el objeto, independientemente de si todavía hay referencias a este objeto. En este caso, la variable no se eliminará del alcance, es decir. de hecho, la variable contendrá un valor indefinido (cero) y, en consecuencia, ocupará memoria para el contenido de esta variable (aproximadamente 72 bytes).
  3. Análisis de la justificación del uso de POO (programación orientada a objetos). Antes de escribir código orientado a objetos, hágase dos preguntas: "¿es necesario aquí un enfoque orientado a objetos?" y "¿puedo escribir código orientado a objetos?". Por ejemplo, definir una función estática dentro de una clase aumenta la cantidad de memoria necesaria solo para contener esa función entre un 10% y un 18%. Usar una matriz como estructura en lugar de una clase también ahorra memoria. Puede ser más beneficioso simplemente colocar las funciones en un archivo separado, en lugar de implementarlas como métodos de clase.
  4. Análisis de la posibilidad de implementar una versión estática de un método en una clase. Si el método no utiliza el parámetro $esto, entonces se debe declarar usando la palabra clave estático.

Acciones para aumentar la velocidad de ejecución del código:

  1. Análisis de la optimización de consultas SQL. En la mayoría de los proyectos, es la optimización de las consultas SQL lo que proporciona el mayor aumento de rendimiento.
  2. El uso de almacenamiento en búfer de salida y varios módulos de almacenamiento en caché le permite aumentar el rendimiento entre un 25% y un 100%.
  3. El uso de nombres cortos para variables, funciones, constantes y clases puede mejorar el rendimiento hasta en un 20%. Al mismo tiempo, no se olvide de la compatibilidad con el código en el futuro; un nombre de función que se explica por sí mismo es mucho más conveniente al modificar el código.
  4. Comprobar la existencia de una variable (función Está establecido()) antes de contactarlo. Suprimir el error que se produce al acceder a una variable inexistente mediante el uso de @ reduce enormemente el rendimiento.
  5. El uso de "comillas simples" le permite interpretar el código más rápido, porque en el caso de "comillas dobles", las variables se buscan dentro de la cadena
  6. Análisis de la posibilidad de eliminar funciones "extra" del ciclo. Por ejemplo, reemplazando la función. contar() a una variable calculada antes del inicio del ciclo y que contiene el resultado de esta función, en la expresión para($i=0; $i mejorará el desempeño de este ciclo. De lo contrario, la función contar() será llamado y ejecutado en cada iteración del bucle.
  7. Uso del operador caso en lugar de uso múltiple de la construcción si... si no.
  8. Usar acceso explícito a los campos de la matriz. Ver reversión $matriz["id"] corre 7 veces más rápido que invertir $matriz. Además, protege contra errores durante el mantenimiento posterior del script, porque. algún día puede haber una constante nombrada identificación.
  9. Usar una variable adicional que contiene una referencia a la matriz final al procesar matrices multidimensionales en un bucle. Para acelerar el ciclo para($i = 0; $i< 5; $i++) $a["b"]["c"][$i] = func($i); , antes del inicio del ciclo es posible escribir la siguiente instrucción $elemento =p$a["b"]["c"] y reescribe el bucle así: para($i = 0; $i< 5; $i++) $ref[$i] = $i; .
  10. El uso de los módulos de Apache mod_gzip y mod_deflate le permite reducir el tráfico, aumentando así la velocidad de carga de las páginas.

Los siguientes pasos de optimización de código mejoran el rendimiento solo cuando se reutilizan:

  1. Uso ++$yo en lugar de $yo++ en ciclos da un aumento de rendimiento del 6%.
  2. Usar "comillas dobles" para concatenar (pegar) variables. Ver instrucciones $s="$s1$s2$s3" interpretado más rápido que $s=$s1.$s2.$s3. Esta afirmación es cierta sólo para tres o más variables.
  3. Uso de rutas completas en instrucciones incluir Y requerir Le permitirá dedicar menos tiempo a buscar una ruta real por parte del sistema.
  4. Cerrar conexiones de bases de datos abiertas cuando ya no sean necesarias. Al mismo tiempo, no debes conectarte a la misma base de datos varias veces.
  5. Análisis de viabilidad de reemplazo. incluir() Y incluir_once() en requerir() Y requerir una vez() respectivamente.
  6. Usar inserciones HTML en el código, en lugar de generar una cantidad significativa de líneas estáticas (que no contienen los resultados del código). En general, la velocidad de generar una página estática (HTML) es varias veces más rápida que la de generar una página escrita en PHP. Pero aquí no debes dejarte llevar, porque. La entrada al intérprete en el modo de procesamiento PHP y la salida también cargan el servidor.
  7. Análisis de la posibilidad de sustitución de funciones. preg_replace Y str_replace en algunos casos. Función str_replace funciona más rápido que preg_replace, y al mismo tiempo la función strtr función más rápida str_replace. Además, usando funciones de cadena strncasecmp, strpbrk Y rayas más óptimo que usar expresiones regulares. Sin embargo, en lugar de anidar estas funciones, debería utilizar funciones de expresión regular.
  8. Usando inicialización de variable explícita. Por ejemplo, incrementar una variable no inicializada es entre 9 y 10 veces más lento que una variable preinicializada. Además, hay menos errores al inicializar variables explícitamente.
  9. Como conclusión, me gustaría señalar que el uso de la construcción. eco, en lugar de una función imprimir, no proporciona un aumento notable en el rendimiento.
  • Para determinar la hora de inicio de la ejecución del script, en lugar de funciones que devuelvan la hora actual, es preferible utilizar $_SERVER["REQUEST_TIME"].
  • Utilice un generador de perfiles para identificar secciones críticas de código.

Antes de optimizar el rendimiento del código, recomiendo encarecidamente verificar la optimización de las consultas SQL a la base de datos, así como optimizar las consultas http, reducir el tamaño de js y css, pensar en el almacenamiento en caché de plantillas y solo después de eso comenzar a verificar el código. actuación.

Un buen estilo de programación consiste en optimizar mientras se escribe el código, no en reparar agujeros más adelante.

Hay una serie de reglas que se deben seguir para aumentar la velocidad de las aplicaciones PHP. Las reglas son simples y no requerirán cambios importantes en las aplicaciones existentes.

fastcgi

FastCGI es una de las opciones para conectar PHP a un servidor web. Se utiliza mejor junto con Nginx. PHP-fpm (contenedor Fastcgi para PHP) y Nginx funcionan juntos de forma predeterminada y son muy fáciles de configurar.

caché de operaciones


¿Cómo se suele ejecutar un script PHP? PHP abre el archivo de código, lo compila y luego lo ejecuta. Dado que puede haber muchos archivos, el proceso de abrirlos, leerlos y compilarlos puede consumir muchos recursos. Si los archivos no cambian, es posible que no se realice una compilación constante. Es mejor hacerlo una vez y almacenar en caché el resultado.

Esto es exactamente lo que hace el módulo opCache. El resultado de la primera compilación se almacenará en el caché, con el que funcionará PHP. Por lo tanto, acelerará la ejecución debido a la ausencia de un proceso de compilación pesado. Cuando los archivos cambian, el módulo mismo restablecerá el caché y garantizará la recompilación. En resumen, este módulo supone un ahorro de recursos muy útil. Y eso sin tener que configurarlo.

A partir de PHP5.5+, este módulo se envía como una versión estándar. En versiones anteriores, debes instalar el módulo tú mismo. Puedes verificar la disponibilidad de esta manera: php -i | opcache grep

# Una salida vacía significará que el módulo no está presente

Si la versión es demasiado temprana, es mejor usar APC: apt-cache search php-apc

# Esta es una alternativa a opCache, pero hace lo mismo

almacenamiento en caché

A menudo el código es simplemente lento. Por ejemplo:

  • acceder a API externas
  • selecciones pesadas de bases de datos
  • procesar archivos grandes
session.save_handler = memcache session.save_path = "tcp:// servidor local: 11211"

# localhost:11211 es el host y puerto predeterminado de Memcache

Además, dicho esquema de almacenamiento permitirá escalar a múltiples servidores.

Optimización de código

POO

¡Recordar! La programación orientada a objetos siempre es lenta. Los objetos deben crearse, almacenarse en algún lugar y destruirse. No utilices objetos si no los necesitas. Por ejemplo, aquí:

set_title($_GET["título"]); $post->set_description($_GET["descripción"]); $post->guardar();

# $posts = lista de objetos Post recibidos de alguna manera foreach ($publicaciones como $publicación) ( echo $publicación->título . "
"; }

# Usar la lista de objetos solo para mostrar la propiedad

En estos ejemplos, usar programación orientada a objetos no tiene mucho sentido. Pero consume recursos. Intente usar matrices cuando no necesite objetos:

$_GET["título"], "descripción" => $_GET["descripción"]]);

# Se evitó crear un objeto, la función simplemente guarda los datos del array en la base

"; }

# Mucho mejor: haga una selección simple y genere los datos deseados de la matriz

Pequeñas cosas

Cuando trabaje con archivos, utilice rutas absolutas. Entonces no se producirán operaciones de búsqueda de archivos innecesarias:

incluir "/var/www/file.php"; file_get_contents("/var/www/dir/data.txt");

Las constantes de clase funcionan de manera más eficiente que las definidas:

publicaciones de clase ( const PER_PAGE = 10; ... )

No utilice funciones en la cláusula for, porque se repetirán en cada iteración del ciclo:

$max = mysql::get_col("SELECCIONAR recuento (*) DE publicaciones"); para ($i = 0; $i< $max; $i++) { ... }

Especifique siempre cadenas como claves de matriz con comillas:

$post["title"] = "Primera publicación";

Utilice las funciones de cadena integradas en lugar de expresiones regulares si es posible.

strpos($post["título"], "bueno");

Utilice cadenas con comillas simples:

$post["title"] = "No hay procesamiento de variables adicional en este caso"

scripts cron PHP

Cuando se utiliza PHP para desarrollar un script que será ejecutado por cron, se debe evitar el uso de variables globales. Por ejemplo:

(.+?)<\/title/", $rss, $coincidencias); }

(.+?)<\/title/", $rss); if ($has_something) $ actualizaciones= tiempo(); $rss = file_get_contents("http://othersource.com/rss"); $tiene_algo = preg_match("/título>(.+?)<\/title/", $rss); if ($has_something) $ actualizaciones= tiempo(); )

La variable $updates ahora crecerá hasta su límite máximo. Cuando se alcance el límite de memoria, el script se detendrá. Hacer un seguimiento de todas las variables es bastante difícil, por lo que es mejor utilizar funciones. Todas las variables creadas dentro de la función se eliminarán una vez que finalice:

proceso(); proceso de función() ( $rss = file_get_contents("http://somesite.com/rss"); $has_something = preg_match("/title>(.+?)<\/title/", $rss); if ($has_something) $updates = time(); $rss = file_get_contents("http://othersource.com/rss"); $has_something = preg_match("/title>(.+?)<\/title/", $rss); if ($has_something) $updates = time(); }

El más importante

  • Asegúrese de utilizar opCache para PHP. Este gratis ahorra recursos.
  • Utilice FastCGI (Nginx + PHP-fpm es lo mejor).
  • Las funciones en las tareas cron ayudarán a evitar pérdidas de memoria.
  • El almacenamiento en caché de secciones lentas de código suele ser la solución más sencilla para acelerar el trabajo.
  • recuerda sobre

El rendimiento de las soluciones PHP es un tema frecuente de diversas disputas y discusiones. No participaremos en ellos ahora. Al fin y al cabo, sea como sea, todo siempre depende de la tarea concreta. Por ejemplo, conozco un caso fiable en el que un determinado código de programa se reescribió en Assembler durante un año y medio. Fue escrito originalmente en C. Cuando se completó el trabajo, quedaron atrás cientos de días de trabajo de un gran grupo de desarrolladores y ya estaba en nuestras manos una versión del software escrita íntegramente en Assembler. ¡Qué sorpresa se llevó el equipo cuando, como resultado, su creación en Assembler funcionó mucho más lento que su creación anterior en C!

La optimización del código es una tarea multifacética. Hay muchos factores a considerar. Debe entenderse que en algunos casos esto puede descuidarse por completo: después de todo, a menudo es más fácil comprar hardware adicional de alto rendimiento que pagar por el trabajo adicional de un equipo de desarrolladores de alto nivel. ¡Automatización, industrialización, amigos míos! Los robots están reemplazando a las personas. Pero una vez hubo profesiones como, por ejemplo, la profesión de farolero o ascensorista, no, no la que ahora repara y mantiene ascensores. El que solía ser el navegante del ascensor y llevaba a los pasajeros a donde pedían. Ahora ya parece ridículo. Y dentro de un cierto número de años, los pilotos de aviones provocarán risas. Estos volarán con sistemas de control totalmente automatizados, etc.

De cualquier manera, no tiene sentido optimizar piezas de software muy simples o poco utilizadas. Al menos hasta que todo lo demás esté en orden. ¿Y a qué deberías prestarle atención exactamente en primer lugar? Ahora hablaremos de esto.

Tomemos PHP como ejemplo. De hecho, no importa lo que digan al respecto, PHP no es peor que Perl o ASP.NET, incluso diría lo contrario: PHP tiene muchas más ventajas. ¿Por qué es el que más lo consigue? Muy simple, ¡porque es el más popular! Después de todo, todo el mundo regaña a Windows, es el que tiene la mayor cantidad de virus, el que tiene más "agujeros" encontrados. Pero su popularidad lo vale... Hmm, más del 98% de los usuarios trabajan con el sistema operativo Windows. Todos los demás sistemas operativos combinados no representan más del 2% de los usuarios. No es de extrañar que Windows reciba tanta atención. Estoy seguro de que si cualquier otro sistema operativo fuera tan popular (y tan complejo, funcional y accesible), no se encontrarían menos agujeros. Bueno, está bien, esta es una conversación para un tema aparte.

Volviendo a PHP, entre otras cosas, este es quizás el lenguaje de programación más sencillo y ampliamente utilizado para la web. Su simplicidad y accesibilidad determinan el ejército emergente de principiantes que intentan hacer al menos algo en él. Su incompetencia a menudo conduce a discusiones negativas sobre PHP. El mismo ASP.NET no es tan accesible. Como resultado, sus principales “portadores” son personas bastante alfabetizadas. Con todas las consecuencias consiguientes. Pero la disponibilidad de PHP de ninguna manera niega sus ventajas en manos de profesionales.

Después de todo, ¿cuál es la red social más popular y el segundo recurso web más visitado del mundo, Facebook? ¿Y su análogo es vkontakte? ¡Por supuesto, en PHP!

Comprenda el alcance. Si necesita realizar cálculos serios, especialmente relacionados con multimedia, con big data y cargas elevadas, por ejemplo, procesamiento de video en línea, por supuesto, es mejor escribir el código correspondiente en el mismo C y usarlo ya en PHP. como un módulo compilado. PHP es más un motor de plantillas universal que un lenguaje de programación tal como lo entendemos. PHP tiene una tarea completamente diferente.

En este sentido, a la hora de optimizar el rendimiento del código PHP, los enfoques son diferentes: aquí es más importante optimizar el algoritmo en sí, el modelo de resolución de problemas, que el código específico. Aunque hay excepciones.

7 principios o 7 posiciones de optimización del código PHP.

1) Amor por las bibliotecas ya preparadas.

Varias bibliotecas listas para usar son definitivamente útiles y convenientes. Pero no debemos olvidar que el queso gratis sólo está en una ratonera. Para todo, de una forma u otra, pero hay que pagar.

Desarrollar software para implementar las ideas de un sitio determinado siempre (sujeto a niveles comparables de desempeño, por supuesto) en términos de rendimiento será mucho más rentable que usar un CMS (Sistema de gestión de contenidos) universal ya preparado - sistema de gestión de contenidos, sitio "motor"). El bajo rendimiento es el costo de la versatilidad del CMS. Esto es lo mismo que ir al mercado en un autobús privado, o incluso en un avión, pero no en tu propio coche. Lo mismo ocurre con las bibliotecas ya preparadas.

Pero, ¿por qué puse las bibliotecas en primer lugar? Porque si se utilizan, inmediatamente se comen la mayor parte de la productividad. Compruébalo tú mismo: Conectando solo Sabelotodo Y DbSimple inmediatamente "come" aproximadamente 0,025 segundos. tiempo y casi 3/4 MB de RAM. Y esto es en un buen servidor con una carga general baja. Añade algo más aquí phpMailer, y tenemos 0,03 seg. tiempo invertido y 1 MB de memoria consumidos simplemente desde cero. Aún no hemos hecho nada, sólo hemos conectado los módulos, ¡incluso sin inicializarlos! Tengo un proyecto escrito por mí mismo, como una red social, por lo que, en promedio, se necesitan muchos menos recursos para crear una página por completo. Otro ejemplo es el motor de un sitio de noticias que desarrollé: publicaciones, comentarios, etc. En general, nada muy complicado, pero la velocidad es decente: en promedio, menos de 0,001 segundos. para generación de páginas y hasta 0,15 MB de memoria. Los proyectos se basan en un montón de PHP + MySQL. Por cierto, de esta forma el segundo de ellos guarda tranquilamente más de 400 mil. visitas por día, con ráfagas de hasta 1600 visitas por minuto con creces y casi 500 hosts en línea. En VPS por $30/mes. Y conecte esas tres bibliotecas a él, entonces no podrá prescindir de un servidor dedicado y ni siquiera de la configuración más débil. Pero a menudo se trata del uso de una docena de bibliotecas ya preparadas.

Por otro lado, por supuesto, si está desarrollando un sitio pequeño, para una empresa o una página personal, no tiene sentido ocuparse de la optimización y, por lo tanto, negarse a utilizar bibliotecas ya preparadas. El tiempo es más valioso. Si el tráfico de su sitio no supera los 1000 visitantes por día, no debe perder el tiempo con un código perfecto y rápido. Utilice bibliotecas ya preparadas. Tendrás recursos suficientes de cualquier buen hosting compartido. Si su tráfico alcanza entre 2 y 3 mil visitantes por día, ya tiene sentido pensar en optimizar el código. Pero aún así, vale la pena pensar detenidamente si abandonar las bibliotecas ya preparadas en esta etapa y matar el tiempo para reelaborar el código (o tiempo y dinero para el programador que lo hará). A menudo es más fácil comprar recursos adicionales o cambiar a VPS, pagando entre 10 y 50 dólares al mes.

Por otro lado, se debe tener en cuenta la complejidad de la transición a soluciones sin el uso de bibliotecas listas para usar. Escribí el mismo motor de sitio de noticias casi en un día. Después de todo, entre otras cosas, los scripts "pesados" no sólo requieren un alojamiento más potente, sino que también ralentizan la apertura de las páginas del sitio en el navegador, especialmente si la página se crea en unos pocos segundos. Si no le resulta muy caro negarse a utilizar bibliotecas ya preparadas, le aconsejo que lo haga de todos modos.

En resumen, enfatizo una vez más: puede usar bibliotecas de manera segura aumentando la capacidad de los servidores, pero no debe olvidar que esta es la primera razón del lento funcionamiento de sus scripts, y además de la alta carga en el hardware, son la causa de muchos retrasos en la carga de las páginas del sitio.

2) Ignorar Zend Optimizer, eAccelerator

Estos fantásticos módulos se ocupan principalmente de la optimización y el almacenamiento en caché dinámico del código PHP compilado ( byte - código). A menudo le permiten aumentar la productividad casi decenas de veces. Su uso tiene sentido, en primer lugar, en proyectos bastante grandes y muy visitados, aunque puede optimizar cualquier otro sitio en PHP; esto no requerirá ninguna manipulación adicional por su parte. Hablaremos más sobre el uso de estos módulos; la próxima vez, este es un tema bastante voluminoso. Por ahora sólo hace falta recordar este punto.

3) Uso "torcido" de las bases de datos

De hecho, este es un tema aparte. Debes recordar que cada conexión a la base de datos, cada consulta, cada tabla adicional en una consulta, etc. - Todo esto crea una carga tangible. Pero aún así, la lógica de la base de datos en sí, y no la interfaz para trabajar con ella, es la que soporta la mayor carga. Recientemente tuve que optimizar un módulo muy popular para uno de los "motores" más populares del foro. Como pude descubrir de inmediato, el mismo módulo era la causa principal de los frenos importantes. Al agregar una tabla pequeña y dos nuevas consultas SQL en código PHP, el rendimiento del foro aumentó entre un 60 y un 80 % (dependiendo de la página), y el consumo de memoria disminuyó entre un 5 y un 7 %. Y casi todo surge de la nada. Como puede ver, este es el caso cuando agregar una tabla "extra" y consultas "extra" aumentan significativamente el rendimiento. No fui extenso, sino intensivo, mejorando la lógica. Y con resultados realmente sorprendentes.

Hablaremos sobre optimización de bases de datos en un futuro próximo. Ahora sólo tocaré el aspecto relacionado con la interfaz de trabajo, tanto en PHP como, por cierto, en cualquier otro lenguaje de programación.

Entonces, antes que nada, use siempre archivos en lugar de una base de datos si eso tiene sentido. ¿Cuándo tiene sentido? Digamos que estás escribiendo un motor de sitio de noticias. La noticia se añade allí de una vez por todas. No está sujeto a cambios posteriores, es grande y sólido. Es mucho más fácil y eficiente colocarlo en un archivo separado que en una base de datos. Pero la revisión de las noticias ya es mejor en la base de datos. De hecho, en determinadas páginas obviamente tendrás que mostrar una lista de reseñas recientes sobre un tema, o una lista de reseñas aleatorias. Si escribimos cada reseña en un archivo separado, cuando mostremos, digamos, 50 reseñas por página, tendremos que incluir la misma cantidad de archivos de reseñas correspondientes. Escribir todas las reseñas en el mismo archivo tampoco es muy bueno: con un gran número de ellas, el archivo será muy grande y solo crecerá con el tiempo, mientras que el rendimiento disminuirá en consecuencia. Sí, y trabajar con este tipo de archivos puede resultar bastante incómodo e inseguro. Otra cuestión es "tirar" nuestras pequeñas reseñas a la base de datos y "sacar" las que necesita con una simple solicitud. Lo mismo se aplica a cualquier dato editado con frecuencia. Por ejemplo, escribir un contador de vistas de noticias en archivos es una gran tontería. Sólo base de datos.

En cuanto a la conexión a la base de datos, conviene cerrarla tan pronto como ya no sea necesaria. Sin embargo, no debe hacer esto si todavía es útil en el trabajo de este script.

Monitorear el contenido de las variables a las que se asignan los resultados de la ejecución de la consulta. Tiene sentido usar desarmado en situaciones donde ya no se necesitan grandes cantidades de datos.

4) Sin almacenamiento en caché

En muchos casos, el almacenamiento en caché es simplemente insustituible. Consideremos un ejemplo sencillo. Un poco más arriba, en lo que respecta a la base de datos, di un ejemplo con una lista de reseñas. Supongamos que vamos a una determinada página que muestra una lista de 50 reseñas de las últimas novedades. Como regla general, todos ellos se pueden seleccionar de la base de datos con una simple consulta. Pero, por otro lado, podemos crear un archivo de antemano que contendrá estas 50 reseñas en su forma terminada. No necesitaremos seleccionarlos de la base de datos, formatearlos según nuestra plantilla e insertarlos en el lugar correcto de la página. Inmediatamente conectamos todo esto desde un archivo pregenerado.

La esencia del almacenamiento en caché es crear un caché de los datos más utilizados y menos modificados. Por ejemplo, ¿con qué frecuencia tienes que actualizar el caché de tus 50 reseñas? Está claro que cada vez se agregan nuevas noticias, para que nuestro caché muestre información actualizada. ¿Con qué frecuencia se agregarán nuevas noticias? Supongamos que aproximadamente cada 15 minutos, es decir hasta 100 veces por día. ¿Y cuál es la asistencia a este sitio? ¿Con qué frecuencia se ven estas reseñas? En el proyecto, cuyo “motor” desarrollé, unas 70 mil veces al día. Así, en lugar de realizar una selección de la base de datos, formatear e insertar estas revisiones 70 mil veces al día, esto generalmente no se hace más de 100 veces, el resto son simples inclusiones de datos completamente terminados.

Siempre que sea posible, debe crear datos finalizados para el almacenamiento en caché, lo cual es bastante sencillo de conectar a la página durante la ejecución de la solicitud, sin la necesidad de análisis, posprocesamiento, creación de plantillas, etc.

No olvide que el caché no tiene por qué almacenarse solo en archivos y no necesariamente es posible almacenar en él solo partes de nuestra futura página HTML. Y especialmente si está sujeto a actualizaciones frecuentes y sistemáticas. Por ejemplo, es mucho más razonable mantener una lista de datos sobre los usuarios que están en línea en la base de datos, en una tabla del tipo Memoria.

5) Búfer, compresión, servidor http frontend

Todo es muy sencillo. Durante la ejecución, todos los datos que se muestran al usuario se le envían inmediatamente. En términos generales, hasta que se eliminan los datos, no se realiza la continuación de la ejecución del código. Entonces, si en el proceso de trabajo su script envía el código HTML terminado a través de la función de eco, por ejemplo, o por cualquier otro método, entonces la cripta transmite los datos "en pedazos", cada vez "colgados". Es mucho más inteligente enviar datos al búfer, algo como esto:

PHP //inicializa el buffering
ob_start (); //ejecución del código del script
//... //finalizar el almacenamiento en búfer, recuperar datos
$html = ob_get_contents ();
ob_end_clean ();
salida( $html ); ?>

Habilitar la compresión dinámica de páginas HTML terminadas (

ob_start(`ob_gzhandler`);

) puede comprimirlos en un promedio de 20-60%, aumentando la velocidad de descarga y reduciendo la cantidad de procesos "colgados". ¿Tiene un límite de tráfico en su hosting? Entonces la compresión dinámica de páginas traerá beneficios dobles.

Eso sí, hay que tener en cuenta que el buffering aumenta ligeramente el consumo de memoria, mientras que la compresión aumenta la carga en el procesador. Pero estos sacrificios a menudo dan sus frutos con un aumento de la velocidad. Y no sólo la velocidad de creación, sino también la velocidad de carga de la página.

Finalmente, un servidor front-end http puede llevar el rendimiento de sus scripts PHP al siguiente nivel. El hecho es que incluso con el almacenamiento en caché, los procesos asociados con la solicitud del usuario se "colgarán" hasta que el usuario acepte todos los datos (o hasta que se alcance el límite de tiempo para ello). La esencia del servidor frontend es recibir datos inmediatamente, lo que le permite descargar inmediatamente los procesos gastados. Es una especie de vínculo entre el usuario y un servidor backend bastante "pesado", donde se ejecutan sus scripts PHP. Pero debido a su "ligereza", el servidor front-end reduce significativamente los recursos consumidos. Nuevamente, este es un tema muy amplio y lo cubriremos con más detalle en un futuro próximo.

6) Inclusión total

Supongamos que ha creado su "motor" en PHP y ha seguido todos los consejos anteriores. Es casi inevitable que haya muchas inclusiones diferentes: archivos de configuración, funciones, idiomas, etc. La conclusión es que incluso la inclusión regular del mismo archivo con funciones requerirá mucho tiempo y memoria, incluso si no hay ningún código ejecutable además de las funciones en la inclusión y no se llama a ninguna de las funciones.

Pero al fin y al cabo las funciones son muy diversas y específicas. Por lo tanto, poner la lista completa de funciones en un archivo e incluirla cada vez no es la mejor solución. Por ejemplo, el sitio tiene registro de usuario: para ello, puede disponer de una serie de funciones especiales que se utilizan sólo durante el registro. Entonces, ¿por qué incluirlos en una lista común de funciones que se conectarán cada vez que acceda a las páginas del sitio?

No descuides la optimización. Elimine lo que no se aplica universalmente en inclusiones separadas y especializadas. Otro ejemplo para reforzar. Mi motor de sitio de noticias favorito. Las funciones para agregar noticias, comentarios, su control y análisis previo ocupan aproximadamente 1/3 del código del número total de funciones. ¿Pero con qué frecuencia se necesitan? ¿En 1 de cada 100 consultas? ¿O 1 entre 200? ¿O incluso con menos frecuencia? Entonces, ¿por qué cargarlos cada vez? De hecho, esto puede reducir significativamente el rendimiento de sus soluciones.

7) Funcionalización extra y timismo OOP

Las funciones sólo deben usarse cuando realmente tengan sentido. Recordemos el propósito básico de las funciones. No es más que comida para llevar.

Se utiliza con frecuencia dentro de un ciclo del programa.

partes del código en una parte común separada. En principio, tiene sentido mover el código a una “parte separada” incluso cuando se ejecuta por algún evento relativamente improbable. Por ejemplo, adjuntar una foto a una publicación en un foro. Mover el controlador de carga y procesamiento de imágenes a una "parte separada" tendrá un efecto positivo en el rendimiento, incluso si está incluido en una condición (el hecho de que la imagen esté cargada). Al mismo tiempo, si necesitamos esta "parte separada" solo una vez, es mejor ejecutarla simplemente como código (incluir) y no como una función. Las funciones siempre requieren algunos recursos adicionales. Lo mismo ocurre con la programación orientada a objetos en PHP. El código OOP consume un poco más de recursos, por lo que si el formato del código OOP no es importante para usted, es mejor abandonarlo. Me refiero específicamente al formato POO, ya que el enfoque POO en PHP tiene poco que ver con el concepto mismo de programación POO. Además de PHP con una comprensión clásica de los lenguajes de programación y sus tareas, sobre lo que escribí al principio.

Entonces se familiarizó con los 7 principios básicos del código PHP productivo. Esto es sólo... sólo el comienzo. Todavía tenemos por delante mucho material interesante y más específico sobre este tema.

Uno de los principales criterios para el éxito de cualquier recurso de Internet es la velocidad de su funcionamiento, y cada año los usuarios se vuelven cada vez más exigentes en este criterio. La optimización de los scripts php es uno de los métodos para garantizar la velocidad del sistema.

En este artículo, me gustaría presentar al público mi colección de consejos y datos sobre la optimización de scripts. La colección fue recopilada por mí durante mucho tiempo, basándome en varias fuentes y experimentos personales.

¿Por qué una colección de consejos y datos y no de reglas estrictas y rápidas? Porque, como he visto, no existe una “optimización absolutamente correcta”. Muchas técnicas y reglas son contradictorias y es imposible cumplirlas todas. Debe elegir un conjunto de métodos que sean aceptables para usar sin sacrificar la seguridad y la conveniencia. He asumido una posición de asesoramiento y, por lo tanto, tengo consejos y datos que usted puede seguir o no.

Para evitar confusiones, dividí todos los consejos y datos en 3 grupos:

  • Optimización a nivel de lógica y organización de la aplicación.
  • Optimización de código
  • Optimización inútil

Los grupos se asignan de forma condicional y algunos elementos se pueden atribuir a varios de ellos a la vez. Las cifras se dan para el servidor promedio (LAMP). El artículo no aborda cuestiones relacionadas con la efectividad de diversas tecnologías y marcos de terceros, ya que este es un tema para discusiones separadas.

Optimización a nivel de lógica y organización de la aplicación.

Muchos de los consejos y datos relacionados con este grupo de optimización son muy importantes y permiten ganar mucho tiempo.

  • Perfile constantemente su código en el servidor (xdebug) y en el cliente (firebug) para identificar cuellos de botella en el código.
    Cabe señalar que es necesario crear un perfil tanto del servidor como del cliente, ya que no todos los errores del servidor se pueden detectar en el propio servidor.
  • La cantidad de funciones definidas por el usuario utilizadas en el programa no afecta la velocidad de ninguna manera
    Esto le permite utilizar una cantidad infinita de funciones definidas por el usuario en el programa.
  • Hacer uso activo de funciones personalizadas
    Se logra un efecto positivo debido al hecho de que dentro de las funciones las operaciones se realizan solo con variables locales. El efecto de esto es mayor que el costo de las llamadas a funciones definidas por el usuario.
  • Es deseable implementar funciones "críticamente pesadas" en un lenguaje de programación de terceros como una extensión de PHP.
    Esto requiere habilidades de programación en un lenguaje de terceros, lo que aumenta enormemente el tiempo de desarrollo, pero al mismo tiempo le permite utilizar trucos que van más allá de las capacidades de PHP.
  • Procesar un archivo html estático es más rápido que un archivo php interpretado
    La diferencia de tiempo en el cliente puede ser de aproximadamente 1 segundo, por lo que tiene sentido una separación clara entre páginas estáticas y generadas por PHP.
  • El tamaño del archivo procesado (conectado) afecta la velocidad
    Se dedican aproximadamente 0,001 segundos al procesamiento cada 2 KB. Este hecho nos empuja a minimizar el código del script al transferirlo a un servidor de producción.
  • Trate de no usar constantemente require_once o include_once
    Estas funciones deben usarse cuando sea posible releer el archivo, en otros casos es deseable usar require e include.
  • Al bifurcar el algoritmo, si hay construcciones que no se pueden procesar y su volumen es de aproximadamente 4 KB o más, entonces es más óptimo incluirlas mediante include.
  • Es recomendable utilizar la validación de los datos enviados en el cliente.
    Esto se debe a que al validar datos del lado del cliente, la cantidad de solicitudes con datos incorrectos se reduce drásticamente. Los sistemas de validación de datos del lado del cliente se crean principalmente utilizando JS y elementos de formato físico (seleccionar).
  • Es deseable crear construcciones DOM grandes para matrices de datos en el cliente.
    Esta es una técnica de optimización muy eficaz cuando se trata de mostrar grandes cantidades de datos. Su esencia se reduce a lo siguiente: se prepara una matriz de datos en el servidor y se transfiere al cliente, y la construcción de estructuras DOM se proporciona a las funciones JS. Como resultado, la carga se redistribuye parcialmente del servidor al cliente.
  • Los sistemas construidos con tecnología AJAX son mucho más rápidos que los sistemas que no utilizan esta tecnología.
    Esto se debe a una disminución en los volúmenes de retiro y a una redistribución de la carga sobre el cliente. En la práctica, la velocidad de los sistemas con AJAX es 2-3 veces mayor. Comentario: AJAX, a su vez, crea una serie de restricciones en el uso de otros métodos de optimización, como trabajar con un búfer.
  • Al recibir una solicitud de publicación, siempre devuelva algo, incluso un espacio.
    De lo contrario, se enviará al cliente una página de error que pesa varios kilobytes. Este error es muy común en sistemas que utilizan tecnología AJAX.
  • Obtener datos de un archivo es más rápido que de una base de datos
    Esto se debe en gran medida al coste de conectarse a la base de datos. Para mi sorpresa, un gran porcentaje de programadores almacena maniáticamente todos los datos en una base de datos, incluso cuando usar archivos es más rápido y conveniente. Comentario: Los archivos pueden almacenar datos que no se buscan; de lo contrario, se debe utilizar una base de datos.
  • No conectarse a la base de datos innecesariamente
    Por una razón que desconozco, muchos programadores se conectan a la base de datos en la etapa de lectura de la configuración, aunque es posible que no realicen más consultas a la base de datos. Este es un mal hábito que cuesta una media de 0,002 segundos.
  • Utilice una conexión de base de datos persistente con una pequeña cantidad de clientes activos simultáneamente
    El beneficio en el tiempo se debe a la ausencia de costos de conexión a la base de datos. La diferencia de tiempo es de aproximadamente 0,002 segundos. Comentario: con una gran cantidad de usuarios, las conexiones persistentes no son deseables. Cuando se trata de conexiones persistentes, debe haber un mecanismo para terminar las conexiones.
  • Usar consultas complejas a bases de datos es más rápido que usar algunas simples
    La diferencia horaria depende de muchos factores (volumen de datos, configuración de la base de datos, etc.) y se mide en milésimas y, a veces, incluso centésimas de segundo.
  • El uso de cálculos secundarios de DBMS es más rápido que los cálculos secundarios de PHP para los datos almacenados en la base de datos.
    Esto se debe al hecho de que para tales cálculos en el lado PHP, se requieren dos consultas a la base de datos (obtener y cambiar datos). La diferencia horaria depende de muchos factores (volumen de datos, configuración de la base de datos, etc.) y se mide en milésimas y centésimas de segundo.
  • Si los datos de muestra de la base de datos rara vez cambian y muchos usuarios acceden a estos datos, entonces tiene sentido guardar los datos de muestra en un archivo.
    Por ejemplo, puede utilizar el siguiente enfoque simple: obtenemos los datos de muestra de la base de datos y los guardamos como una matriz serializada en un archivo, luego cualquier usuario usa los datos del archivo. En la práctica, este método de optimización puede dar lugar a un aumento múltiple en la velocidad de ejecución del script. Comentario: Al utilizar este método, es necesario escribir herramientas para generar y modificar los datos almacenados en el archivo.
  • Datos en caché que rara vez cambian con Memcached
    La ganancia de tiempo puede ser bastante significativa. Comentario: El almacenamiento en caché es efectivo para datos estáticos, para datos dinámicos el efecto se reduce y puede ser negativo.
  • Trabajar sin objetos (sin programación orientada a objetos) es aproximadamente tres veces más rápido que trabajar con objetos
    La memoria es "devorada" también más. Desafortunadamente, el intérprete de PHP no puede manejar la programación orientada a objetos tan rápido como las funciones normales.
  • Cuanto mayor es la dimensión de las matrices, más lento funcionan.
    La pérdida de tiempo surge del procesamiento del encajado de estructuras.

Optimización de código

Estos consejos y datos dan un ligero aumento en la velocidad en comparación con el grupo anterior, pero en conjunto, estas técnicas pueden brindar una buena ganancia de tiempo.

  • echo e print son significativamente más rápidos que printf
    La diferencia horaria puede ser de hasta varias milésimas de segundo. Esto se debe a que printf se utiliza para generar datos formateados y el intérprete verifica toda la línea en busca de dichos datos. printf solo se usa para generar datos que necesitan formato.
  • echo $var."text" es más rápido que echo "$var."text"
    Esto se debe a que el motor PHP en el segundo caso se ve obligado a buscar variables dentro de la cadena. Para grandes cantidades de datos y versiones anteriores de PHP, las diferencias horarias son notables.
  • echo "a" es más rápido que echo "a" para cadenas sin variables
    Esto se debe a que en el segundo caso el motor PHP intenta encontrar las variables. Para grandes cantidades de datos, las diferencias en el tiempo son bastante notables.
  • echo "a","b" es más rápido que echo "a"."b"
    La salida de datos separados por comas es más rápida que los datos separados por puntos. Esto se debe a que la concatenación de cadenas ocurre en el segundo caso. Para grandes cantidades de datos, las diferencias en el tiempo son bastante notables. Nota: esto sólo funciona con la función echo, que puede tomar varias líneas como argumentos.
  • $retorno="a"; $retorno.="b"; eco $retorno; más rápido que el eco "a"; hacer eco "b";
    La razón es que la salida de datos requiere algunas operaciones adicionales. Para grandes cantidades de datos, las diferencias en el tiempo son bastante notables.
  • ob_inicio(); hacer eco de "a"; hacer eco "b"; ob_end_flush(); más rápido que $return="a"; $retorno.="b"; eco $retorno;
    Esto se debe a que todo el trabajo se realiza sin acceder a variables. Para grandes cantidades de datos, las diferencias en el tiempo son bastante notables. Comentario: Esta técnica no es efectiva si estás trabajando con AJAX, ya que en este caso es deseable devolver los datos como una sola línea.
  • Utilice "inserto profesional" o? > a b
    Los datos estáticos (código externo) se procesan más rápido que la salida PHP. Esta técnica se llama inserción profesional. Para grandes cantidades de datos, las diferencias en el tiempo son bastante notables.
  • readfile es más rápido que file_get_contents, file_get_contents es más rápido que require y require es más rápido que include para generar contenido estático desde un solo archivo
    El tiempo para leer un archivo vacío fluctúa desde 0,001 para readfile hasta 0,002 para include.
  • require es más rápido que include para archivos interpretados
    Comentario: al bifurcar el algoritmo, cuando es posible no usar el archivo interpretado, debes usar include, porque require siempre incluye un archivo.
  • if (...) (...) else if (...) () es más rápido que cambiar
    El tiempo depende del número de sucursales.
  • if (...) (...) else if (...) () es más rápido que if (...) (...); si(...)();
    El tiempo depende del número de sucursales y condiciones. Debería utilizar else siempre que sea posible, ya que es la construcción "condicional" más rápida.
  • Las condiciones más comunes de la construcción if (...) (...) else if (...) () deben colocarse al principio de la rama.
    El intérprete escanea la estructura de arriba a abajo hasta que encuentra una condición. Si el intérprete encuentra que se cumple la condición, entonces no mira el resto de la estructura.
  • < x; ++$i) {...} быстрее, чем for($i = 0; $i < sizeOf($array); ++$i) {...}
    Esto se debe a que en el segundo caso, la operación sizeOf se ejecutará en cada iteración. La diferencia de tiempo de ejecución depende de la cantidad de elementos de la matriz.
  • x = tamañoDe($matriz); para($i = 0; $i< x; ++$i) {...} быстрее, чем foreach($arr as $value) {...} для не ассоциативных массивов
    La diferencia horaria es significativa y aumenta a medida que crece la matriz.
  • preg _replace es más rápido que ereg_replace, str_replace es más rápido que preg_replace, pero strtr es más rápido que str_replace
    La diferencia horaria depende de la cantidad de datos y puede alcanzar varias milésimas de segundo.
  • Las funciones de cadena son más rápidas que las expresiones regulares
    Esta regla es consecuencia de la anterior.
  • Elimine las variables de matriz que ya son innecesarias para liberar memoria.
  • Evite utilizar la supresión de errores @
    La supresión de errores produce una serie de operaciones muy lentas y, dado que la tasa de repetición puede ser muy alta, la pérdida de velocidad puede ser significativa.
  • if (isset($str(5))) (...) es más rápido que if (strlen($str)>4)(...)
    Esto se debe a que se utiliza la operación de verificación isset estándar en lugar de la función de cadena strlen.
  • 0.5 es más rápido que 1/2
    La razón es que en el segundo caso se realiza una operación de división.
  • El retorno es más rápido que el global cuando se devuelve el valor de una variable de una función.
    Esto se debe a que en el segundo caso se crea una variable global.
  • $row["id"] es más rápido que $row
    La primera opción es 7 veces más rápida.
  • $_SERVER['REQUEST_TIME'] es más rápido que time() para determinar cuándo se debe ejecutar un script
  • if ($var===null) (...) es más rápido que if (is_null($var)) (...)
    La razón es que no se utiliza una función en el primer caso.
  • ++i es más rápido que i++, --i es más rápido que i--
    Esto se debe a una característica del núcleo de PHP. La diferencia horaria es inferior a 0,000001, pero si repite estos procedimientos miles de veces, observe más de cerca esta optimización.
  • Incremento de la variable inicializada i=0; ++yo; más rápido que ++i no inicializado
    La diferencia de tiempo es de aproximadamente 0,000001 segundos, pero debido a la posible frecuencia de repetición, conviene recordar este hecho.
  • Usar variables "usadas" es más rápido que declarar nuevas
    O para reformularlo de otra manera: no cree variables innecesarias.
  • Trabajar con variables locales es aproximadamente 2 veces más rápido que con variables globales
    Aunque la diferencia de tiempo es inferior a 0,000001 segundos, debido a la alta tasa de repetición, conviene intentar trabajar con variables locales.
  • Acceder directamente a una variable es más rápido que llamar a una función dentro de la cual esta variable está definida varias veces
    Se necesita aproximadamente tres veces más tiempo para llamar a una función que para llamar a una variable.

Optimización inútil

En la práctica, varios métodos de optimización no tienen un gran impacto en la velocidad de ejecución del script (la ganancia de tiempo es inferior a 0,000001 segundos). A pesar de esto, dicha optimización es a menudo objeto de controversia. He traído estos datos "inútiles" para que no les prestes especial atención cuando escribas código más adelante.

  • eco es más rápido que imprimir
  • include("ruta absoluta") es más rápido que include("ruta relativa")
  • sizeOf es más rápido que contar
  • foreach ($arr as $key => $value) (...) es más rápido que reset($arr); while (list($key, $value) = each ($arr)) (...) para matrices asociativas
  • El código no comentado es más rápido que el código comentado porque lleva más tiempo leer el archivo.
    Es muy estúpido reducir el volumen de comentarios para optimizarlo, solo necesita minimizarlo en los scripts de trabajo ("combate").
  • Las variables con nombres cortos son más rápidas que las variables con nombres largos
    Esto se debe a la reducción en la cantidad de código que se procesa. Al igual que en el punto anterior, sólo necesitas minimizarlo en los scripts de trabajo (“de combate”).
  • El marcado de código usando tabulaciones es más rápido que usar espacios
    Similar al punto anterior.

Finalmente, quiero recordarles una vez más que los consejos y hechos que he dado no son absolutos y la importancia de su aplicación depende de la situación específica. Hay que recordar que la optimización del script es sólo una pequeña parte de todo el procedimiento de optimización y, a menudo, es posible vivir sin los consejos anteriores.


Si tiene alguna pregunta, utilice nuestro

  • ¿Cómo optimizar el sitio y acelerar su trabajo?
  • ¿Qué tan rápido funcionará el sitio y podrá funcionar, de acuerdo con las tecnologías en las que se lanzará?
  • ¿Qué tecnologías se deben utilizar al configurar un servidor o VPS?

Problema típico:
En algún momento, el sitio comienza a abrirse y a funcionar demasiado lento. Sucede que la empresa de hosting bloquea el sitio por exceder la carga o abusar de los recursos. ¿Qué hacer en tal situación?

Tal vez el sitio se haya vuelto demasiado popular, o se haya instalado algún módulo que consume muchos recursos, se esté realizando un ataque o el sitio esté infectado con un virus. De una forma u otra, pero todos estos casos tienen algo en común y esto es un problema para todos los sitios en todos los hostings.

Y si hablamos de servidores PHP, entonces ese problema es la forma en que se ejecuta el código PHP, al igual que otras configuraciones importantes del entorno del servidor.
Independientemente de si hay un problema en su código o no, si su asistencia es alta o no, mucho depende de la configuración del servidor. Para que todo lo dicho no suene a palabras vacías, se redactó este artículo.

En esta revisión, probaré un sitio recién instalado en uno de los motores de administración de contenido más comunes. Drupal 7.33.

Para la prueba, solo se seleccionó un componente de php-hosting. Probaremos servidores web. nginx Y apache2, módulos mod_php Y php-fpm, versiones php php53 Y php56, veamos cómo afectan los optimizadores apc Y opcache velocidad en el sitio.


Por supuesto, estos parámetros son sólo una parte de la configuración de la que depende la velocidad del sitio. Pero deliberadamente
Nos limitamos a esto, para no hacer la reseña interminable.

Dado:
  • Sistema operativo Centos 6.7
  • Servidor de base de datos: MariaDB 10.21
  • Todas las sesiones del sitio se almacenan en Memcache para eliminar la influencia de la velocidad de configuración de la sesión en la velocidad del sitio.
  • En todas las pruebas, el servidor web nginx 1.93 actúa como interfaz. En el caso de Apache2, Nginx actúa como equilibrador de carga además de ofrecer estática. En configuraciones sin utilizar Apache2 - el servidor web directo es Nginx
  • La configuración de Nginx y MariaDB contiene muchas optimizaciones destinadas a lograr el máximo rendimiento, pero para todos los participantes de la prueba estas configuraciones son las mismas y, por lo tanto, se debe ignorar su influencia.
  • Los parámetros opcache y apc se toman de las recomendaciones de Bitrix, ya que son óptimos y universales para la mayoría de los sitios.
¿Cómo lo probaremos?

Hay un servidor zabbix en la red local y sus tareas cada minuto:

  • Abra la página principal del sitio bajo prueba, espere cierto contenido en la página, verifique que la respuesta del servidor sea un código 200.
  • El siguiente paso es la autorización en el panel de administración del sitio, esto ocurre enviando la solicitud POST correspondiente. Verificación del texto y código de respuesta en la página con el estándar incorporado. Este paso afecta a casi todos los subsistemas del servidor web y, en muchos aspectos, su velocidad depende de la velocidad de interacción con la base de datos.
  • El último paso es cerrar sesión en el área de administración del sitio, verificar el código de respuesta y el texto en la página de salida.
  • Al final de cada paso, zabbix medirá y registrará meticulosamente la velocidad de renderizado del código php en html comprensible para el navegador y nos mostrará gráficos de los resultados.
  • Para cada asignatura se registrarán valores durante una hora y el resultado serán los valores medios de esa hora.
  • Las pruebas se realizarán dentro de la red local, por lo que se excluye el impacto en el resultado de la velocidad de la conexión a Internet.
  • Para facilitar la percepción, todos los resultados se muestran en orden ascendente. Aquellos. el primer resultado es el más lento. Todas las configuraciones se colocaron bajo un número condicional, esto le permitirá navegar mejor por los resultados.
  • Gráficos superiores: velocidad de generación de código, cuanto mayor sea el valor, mejor. Los gráficos más bajos son el tiempo de respuesta del servidor y cuanto menor sea el valor, mejor
  • Los sitios probados viven su propia vida, tienen operaciones regulares de bases de datos y tareas programadas, por lo que la curva en los gráficos puede tener altibajos.

Pruebas:

1. Nginx + php-fpm56 sin optimizador de opcache

Arquitectónicamente, esta es una de las opciones más avanzadas. En términos de rendimiento, la mayor decepción.

El rendimiento deja mucho que desear, pero esta opción resistirá la carga mucho mejor que la opción n.° 2 con Apache2. Además, esta opción consumirá RAM de forma mucho más eficiente.

2. Apache2 + mod_php53 sin optimizador apc

La opción más típica de hosting. El 90% de los proveedores de hosting populares utilizan esta opción. Aunque los desarrolladores no admiten php53 desde hace mucho tiempo, hay muchos sitios en Internet que todavía funcionan con esta versión.

Esta opción no sólo es muy lenta, sino que también falla rápidamente bajo carga ligera debido a la falta de procesos de trabajo de Apache2 o a la falta de RAM en el servidor.

3. Equilibrio y estática vía Nginx, parte dinámica de Apache2 + mod_php56 sin optimizador de opcache

Esta opción fue creada como una solución para sitios modernos. Lo ofrecen empresas de hosting que se esfuerzan por ofrecer la última versión de PHP. Según la creencia popular, esta versión de PHP debería ser más rápida y segura que las anteriores.

Desafortunadamente, no todos los sitios pueden funcionar completamente con esta versión. Casi todas las nuevas versiones de PHP dejan de admitir algunas funciones obsoletas y "inseguras", rompiendo el código "antiguo".
Por sí solo, php56 sin un optimizador es bastante lento y mod_php tiende a fallar y ocupar toda la memoria del servidor bajo carga.

4. Nginx + php-fpm53 sin optimizador apc

Configuración bastante avanzada para aquellos que no quieran tener problemas por errores con el optimizador de código. Esto utiliza una versión "compatible" del intérprete PHP y también elimina del paquete Apache2, que consume muchos recursos.

5. Equilibrio y estática a través de Nginx, parte dinámica de Apache2 + mod_php53 + apc

Otra variación común. Muchas empresas de hosting lo utilizan y lo utilizan de forma predeterminada o le permiten habilitar el optimizador en sus paneles de control.
Por lo general, se deja que Apache2 maneje las reglas .htaccess como la traducción de enlaces y CNC.

Obtenemos un aumento de velocidad de 3,5 veces, en comparación con la opción sin utilizar el optimizador.
El propio Apache (cuando usa su propio módulo mod_php) consume muchos más recursos para ejecutarse que la versión php-fpm. Apache2 tiende a fallar si uno de sus módulos falla o llena toda la RAM del servidor.

6. Nginx + php-fpm53 + apc

Una excelente opción para sitios con motores más antiguos que no requieren .htaccess complejo

Esta es la opción que utilizo cuando es necesario mejorar un sitio obsoleto, lograr una velocidad satisfactoria y un funcionamiento confiable bajo cargas elevadas.

7. Equilibrio y estática a través de Nginx, parte dinámica de Apache2 + php-fpm53 + apc

Opción para sitios heredados con .htaccess complejo. Por ejemplo, instalaciones antiguas de Bitrix.

Esto es ideal para sitios heredados. Esta configuración es resistente a cargas elevadas, compatible y suficientemente productiva.
Ideal para cuando necesitas reglas .htaccess y módulos Apache2 adicionales.
De las deficiencias: una versión de PHP desactualizada y no actualizada, pero si no hay otra opción, esta es la mejor opción. Ideal para versiones antiguas de Bitrix, Joomla y otros CMS comunes, no para las últimas versiones.

8. Equilibrio y estática a través de Nginx, parte dinámica de Apache2 + mod_php56 + opcache

Configuración bastante productiva, pero que requiere muchos recursos, con todas las deficiencias de mod_php.

Lo suficientemente rápido, pero bajo carga, el servidor puede quedarse sin memoria y la velocidad disminuirá significativamente.

9. Nginx + php-fpm56 + opcache

La opción más productiva.

Esta es la mejor opción para todos los sitios modernos. Mantiene bien la carga y muestra el mejor resultado en términos de rendimiento. Esta es la opción que utilizo cuando la tarea es optimizar el rendimiento del sitio y aumentar la velocidad de su trabajo.
El único inconveniente es que no podremos usar .htaccess y todas las reglas mod_rewrite deben reescribirse en la sintaxis de Nginx.
Los módulos Apache2 tampoco funcionarán. Si se utilizan, esta opción no funcionará.

10. Equilibrio y estática vía Nginx, parte dinámica de Apache2 + php-fpm56+ opcache

La mejor opción para sitios que necesitan .htaccess. Ideal para versiones nuevas de Bitrix.

Mantiene bien la carga gracias a php-fpm. Utilizo activamente esta opción para la mayoría de los sitios.

Página principal del sitio de prueba.
Número de configuración Arquitectura Respuesta promedio ms.
1 77,04 103,6
2 78,79 103,98
3 78,85 102,38
4 81,55 97,88
5 Apache2 + mod_php53 + apc 303,37 29,36
6. nginx + php-fpm53 + apc 312,33 24,73
7. Apache2 + php-fpm53 + apc 339,63 23,32
8. 484,96 16,91
9. nginx + php-fpm56 + opcache 546,34 14,08
10. Apache2 + php-fpm56 + opcache 571,14 13,78
Autorización en el panel de administración del sitio de prueba.
Número de configuración Arquitectura Velocidad media de descarga kb. Respuesta promedio ms.
1 Nginx + php-fpm56 sin optimizador de opcache 67,51 239,01
2 Apache2 + mod_php53 sin optimizador apc 64,61 257,51
3 Apache2 + mod_php56 sin optimizador de opcache 66,75 242,42
4 Nginx + php-fpm53 sin optimizador apc 68.79 233.15
5 Apache2 + mod_php53 + apc 173,81 94,26
6. nginx + php-fpm53 + apc 173,3 91,3
7. Apache2 + php-fpm53 + apc 182,1 90,5
8. Apache2 + mod_php56 + opcache 218,35 77,55
9. nginx + php-fpm56 + opcache 252,83 62,25
10. Apache2 + php-fpm56 + opcache 262,8 60,85
Cerrar sesión en el panel de administración del sitio de prueba
Número de configuración Arquitectura Velocidad media de descarga kb. Respuesta promedio ms.
1 Nginx + php-fpm56 sin optimizador de opcache 41,01 184,49
2 Apache2 + mod_php53 sin optimizador apc 42,42 188,97
3 Apache2 + mod_php56 sin optimizador de opcache 42,06 188,37
4 Nginx + php-fpm53 sin optimizador apc 45,48 169,15
5 Apache2 + mod_php53 + apc 190,1 41,87
6. nginx + php-fpm53 + apc 185,92 41,24
7. Apache2 + php-fpm53 + apc 202,78 39,21
8. Apache2 + mod_php56 + opcache 315,56 26,23
9. nginx + php-fpm56 + opcache 373,19 20,43
10. Apache2 + php-fpm56 + opcache 381,21 20,57

Como un resumen:

  • En la vida real, todas las opciones de Apache2 pueden ser más lentas, porque en mis pruebas pasé intencionalmente la retroalimentación estática de Nginx. Esto se hace para excluir la influencia de la velocidad de retorno estático en los resultados de medir la velocidad del intérprete PHP. Uno de los lados más débiles de Apache2 y al mismo tiempo el lado más fuerte de Nginx es la velocidad de carga de estadísticas. Esto se nota especialmente con cargas elevadas. Además, Nginx es menos susceptible a ataques de "conexiones lentas".
  • mod_php consume toda la memoria disponible del servidor muy rápidamente y pierde rendimiento en las cargas
  • php-fpm es mucho más eficiente en memoria, más seguro y más flexible en su configuración. En algunos casos, es más rápido y sin cargas elevadas.
  • La prueba tiene una especificidad limitada, aquí vimos las características del motor Drupal, otros pueden comportarse de manera diferente, pero la tendencia general será la misma.

Y lo más importante, la velocidad de su sitio depende de la configuración de su servidor o hosting. Al elegir la arquitectura adecuada, puede multiplicar por cinco la velocidad del sitio.

Si tienes dudas, dificultades o necesitas asesoramiento:
mis contactos en



¿Te gustó el artículo? Compártelo