Observé de cerca el consumo de memoria de Wordpress. En mi sitio, parece que por cada golpe de página se asignan 20 MB de RAM, solo para preparar un entorno cómodo para que se ejecuten todos los complementos. Lo tracé así:
No hay un solo lugar para optimizar, ningún malo que se coma la mayor parte de la memoria. El consumo se extiende por muchos, muchos, muchos módulos php.
¿Cómo podemos hacer que Wordpress inicialice su entorno en la memoria solo una vez, y luego reutilizarlo muchas veces para cada golpe? No quiero que PHP lento coma 20 MB con cada clic de usuario; incluso en un servidor con mucha memoria, lleva segundos realizar todo ese trabajo. Básicamente, necesitaría fragmentos de memoria de solo lectura que se puedan reutilizar.
Además ... ¿por qué 20MB? ¿Alguien puede proporcionar información sobre esto?
Editar: Aquí está la salida de WinCacheGrind en Wordpress ejecutándose en mi máquina de desarrollo (mucho más rápido que el alojamiento compartido). Como puede ver, toma más de un segundo de procesamiento solo para producir el HTML de la página principal. Disminuya la velocidad con alojamiento compartido y tendrá una receta para los problemas. Elegí el método que lleva la mayor parte del tiempo. ¿Cómo harías para optimizar esto?
Editar: Aquí hay estadísticas de consultas de esta fantástica herramienta de creación de perfiles functions.php .
Carga: 12 consultas - 532 ms - 19,1 MB - 43 aciertos de caché / 53 Consulta: 15 consultas - 563ms - 19.0MB - 72 aciertos de caché / 86 Pantalla: 21 consultas - 705 ms - 19,2 MB - 234 aciertos de caché / 257
Editar: ¿Quieres ver algo garantizado que te asuste? Inserte estas líneas al final de index.php:
echo "<pre>\n";
print_r(get_defined_vars());
echo "</pre>\n";
Traté de contar cuántas veces se almacena el cuerpo de la publicación actual en la memoria. Conté 20 instancias. Luego me di cuenta de que PHP tiene un recuento de referencias, por lo que la cantidad de copias se redujo a solo tres: dos parecen estar en WP_Query, una en la caché de objetos. Estoy investigando más a fondo.
Es por eso que creo que WordPress necesita una refactorización dirigida a los problemas de memoria. Ya no puede culpar a su consumo de memoria de la complejidad de lo que hace. Simplemente hace un montón de cosas mal .
Editar: Después de un día de tratar de resolver esto, aquí están mis hallazgos:
1) El 88% de toda la memoria proviene del tipo de llamadas require o include o include_once:
2) El archivo php incluye suceder principalmente durante la primera parte de servir una solicitud (no es sorprendente), que también es donde se consume toda la memoria:
3) Es bastante interesante trazar todas las funciones que se ejecutan durante una solicitud. Hay más de 12000 llamadas en total. Los jitteé para hacerlo más visible (el eje Level es básicamente la profundidad de la pila):
4) La única forma de avanzar que se me ocurre es minimizar la cantidad de archivos .php incluidos. Si divido las funciones por archivo de donde provienen, puede ver que muchos archivos se golpean una o dos veces como máximo. Necesitamos una forma de omitirlos cuando no son necesarios. Por ejemplo, mi complemento de copia de seguridad de la base de datos remota se carga y se registra, para que nunca se use en absoluto. Aquí está el diagrama anterior dividido por nombre de archivo:
Ofrezco una recompensa que vale toda mi reputación :) por refactorizaciones que conducirían a reducir la huella de memoria de mis blogs en un 30% o más.
Editar: instalé WP 3.1, aquí hay una comparación con la versión anterior.
El azul es WP 3.1, el rojo es 3.0.4. El nuevo WP es más rápido, pero también consume más memoria.
Aquí hay una lista por archivo de inclusión.
Esto me permite darme cuenta de la cantidad de memoria que consume el "paquete All In One SEO": una forma sería utilizar solo una fracción de la funcionalidad del complemento para obtener lo que quiero. Además, mis propios complementos parecen ser bastante malos.
Me gustaría probar la carga condicional en, por ejemplo, comment.php (no permitir comentarios en mi blog) y varios otros. Eliminé todo el código obsoleto. Recorté kses.php para cargar solo sus tablas globales a pedido. Simplifiqué l10n (no hago localización), haciendo que sus funciones devuelvan las cadenas de inmediato, sin búsquedas. Todavía estoy lejos de la marca del 30% que configuré arbitrariamente.
Editar: descargué y habilité APC con la configuración predeterminada (32 MB de caché de código de operación). Aquí está la comparación:
Puede ver que la carga del código se aceleró enormemente, y el código también ocupa menos espacio en la memoria (probablemente porque tratamos solo con códigos de operación, no con la fuente original). Sin embargo, el consumo de memoria sigue siendo bastante alto.