He estado evaluando el rendimiento de un marco que estoy escribiendo en Perl y estoy recibiendo un 50% de disminución en las solicitudes por segundo sobre nuestra base de código existente (algunos aciertos son comprensibles, porque vamos desde el código de espagueti de procedimientos a un marco OOP MVC).¿Cómo puedo ejecutar código ineficiente solo en tiempo de compilación cuando uso mod_perl?
La aplicación se está ejecutando en mod_perl, y he agregado Moose y todo mi código de marco en el startup.pl script, que duplicó mis solicitudes por segundo. Estoy buscando mejorar aún más este número para acercarlo lo más posible a la cantidad existente. El argumento es que esta es una optimización prematura, pero hay un par de ineficiencias flagrantes que me gustaría solucionar y ver cómo afecta el rendimiento.
Al igual que la mayoría de los marcos, tengo un archivo de configuración y un despachador. La parte de configuración es manejada por Config::General, por lo que se requiere un poco de IO y análisis para obtener mi archivo de configuración cargado en la aplicación. ¡El problema más grande que veo aquí es que estoy haciendo esto por CADA PETICIÓN que entra!
Ejecutando Devel :: Dprof en mi aplicación apunta a Config :: General :: BEGIN y un grupo de módulos de IO relacionados como uno de los principales puntos lentos que no es Moose. Entonces, lo que me gustaría hacer, y lo que tiene más sentido en retrospectiva es aprovechar la persistencia de mod_perl y las cosas de compilación de startup.pl para hacer solo el trabajo de cargar en el archivo de configuración una vez, cuando el servidor se inicie.
El problema es que no estoy muy familiarizado con la forma en que esto funcionaría.
Actualmente cada proyecto tiene una clase de programa previo PerlHandler que es bastante delgado y se ve así:
use MyApp;
MyApp->new(config_file => '/path/to/site.config')->run();
MyApp.pm hereda del módulo de Proyecto de marco, que tiene este código:
my $config = Config::General->new(
-ConfigFile => $self->config_file,
-InterPolateVars => 1,
);
$self->config({$config->getall});
Para hacer esto solo en tiempo de compilación, tanto mi bootstrap como los módulos base del Proyecto tendrán que cambiar (creo), pero no estoy seguro de qué cambios realizar y aún así mantener el código agradable y sin problemas. Puede alguien señalarme la dirección correcta?
ACTUALIZACIÓN
He probado el bloque BEGIN en cada enfoque módulo de proyecto según lo descrito por ysth en su respuesta. Así que ahora tengo:
package MyApp::bootstrap;
use MyApp;
my $config;
BEGIN
{
$config = {Config::General->new(...)->getall};
}
sub handler { ..etc.
MyApp->new(config => $config)->run();
Este cambio rápido solo me dio un aumento50% en solicitudes por segundo, lo que confirma mi pensamiento de que el archivo de configuración fue un importante cuello de botella pena de fijación. La cifra de referencia en nuestra vieja máquina dev de crotchety es 60rps, y mi marco ha pasado de 30rps a 45rps con este cambio solo. Para aquellos que dicen que Moose es lento y tiene un tiempo de compilación alcanzado ... Obtuve el mismo (50%) aumento cuando compilé todo mi código Moose en la puesta en marcha como lo hice al precompilar mi archivo de configuración.
El único problema que tengo ahora es que esto viola el principio DRY ya que el mismo código Config :: General-> nuevo está en cada bloque BEGIN con solo la ruta al archivo de configuración que difiere. Tengo algunas estrategias diferentes para limitar esto, pero solo quería publicar los resultados de este cambio.
El problema con esta solución es que debe crear este bloque BEGIN con ese código para cada módulo de proyecto (cada proyecto tiene su propio archivo de configuración). Lo puse rápidamente y obtuve un 50% de aumento en las solicitudes por segundo, así que estoy votando la respuesta de todos modos, porque responde mi pregunta –
Para evitar el "cada proyecto necesita su propia configuración", podrías 1) Combine todos los archivos en 1 con diferentes secciones (podría usar un archivo INI o Config :: ApacheFormat). 2) tienen una clase de configuración que mantiene cada archivo de configuración en un hash y extrae el correcto basado en algunas var. $ ENV. – mpeters
Nunca consideré tener un gran archivo de configuración por lo difícil que sería mantenerlo cuando tienes cientos de proyectos ... pero en realidad hay muchos beneficios al hacer algo así, ya que compartimos conexiones de bases de datos en todos los proyectos, excepto en un puñado de casos. Gracias. –