Parece ser que las prestaciones, en cuestión de velocidad y memoria, se volvían pésimas, comparadas con lo que obtenían en una máquina con BSD. Incluso con máquinas personales. Investigando un poco, descubrieron un fallo en el Perl compilado distribuido por Red Hat. Primero, lo parchearon según se comentaba en la página de seguimiento de fallos, pero era una solución temporal, ya que el programa seguía enlenteciendose poco a poco.
La solución final fue muy sencilla: volver a compilar el ejecutable perl desde las fuentes. Los resultados fueron sorprendentes. Así como la reflexión final...
Redhat perl. ¡Qué tragedia!
En mi nueva empresa, Slaant, usamos Perl un montón. Usamos Perl para el análisis sintáctico de enormes cantidades de documentos HTML/XML; hemos escrito un almacén casero de RDF y tenemos un conjunto de aplicaciones web construidas sobre Catalyst. Usamos máquinas OS X para el desarrollo y CentOS 5.2 para producción. La pasada semana instalamos nuevo hardware -más de 150 núcleos, esperando obtener mucho más poder de procesamiento en el flujo de trabajo de unos 30 subsistemas Perl- pero el aumento de prestaciones fue marginal y Perl se destacó como el culpable. Era más de un año de trabajo, corriendo en un entorno hardware ajustado para producción por primera vez, y las mediciones no resultaban adecuadas. Estuvimos a punto de tirar a Perl por la ventana.
Tenemos un FreeBSD apartado en nuestro entorno de producción y noté que con el programa Perl que la lectura de estructuras JSON desde ficheros en disco era 100 veces más rápida en este ordenador comparada con nuestros ordenadores con CentOS. Debería estar el cuello de botella en la entrada/salida a disco, pero strace mostró una gran actividad de CPU en el espacio de usuario. Sorprendido, ejecuté el fantástico Devel::NYTProf y descubrí que la llamada más costosa, por un gran margen, era un "bless". ¿¡bless!?. Perl puede hacer felizmente millones de bendiciones por segundo en mi macbook a 2ghz. Y esto era un servidor doble 2.5ghz con cuádruple núcleo. ¿Qué demonios?
Algunas investigaciones revelaron que existía un gran error en el Perl de Redhat que causa una severa degradación de prestaciones en el código que usa la combinación "bless/overload". El hilo al respecto está aquí: https://bugzilla.redhat.com/show_bug.cgi?id=379791
En este hilo, ritz mostraba el siguiente trozo de código. Pruébalo. Debe tardar menos de un segundo si el perl no está roto, y mucho más si lo está.
Using perl Syntax Highlighting
#!/usr/bin/perl
use overload q(<) => sub {};
my %h;
for (my $i=0; $i<50000; $i++) {
$h{$i} = bless [ ] => 'main';
print STDERR '.' if $i % 1000 == 0;
}
use overload q(<) => sub {};
my %h;
for (my $i=0; $i<50000; $i++) {
$h{$i} = bless [ ] => 'main';
print STDERR '.' if $i % 1000 == 0;
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
No existe aún un arreglo oficial, pero en este hilo hay un parche. Aplicamos el parche. Sin embargo, no hizo que el problema se fuera, solo lo retrasó: los procesos perl usando "bless/overload" comenzaban a enlentecerse (y continúan haciéndolo exponencialmente) después de un rato. En este punto decidí recompilar perl desde el código fuente. El error desapareció. Y la diferencia fue terrible. Todo se volvió realmente rápido. Las CPU seguían frías con una carga media por debajo de 0.10 ¡y procesábamos datos de entre 100 a 1000 veces más rápido! Estaba aturdido. Era una locura. Arrancamos uno de los procesos, uno que analizaba sintácticamente unos 25 millones de documentos HTML usando el módulo HTML::TreeBuilder::XPath porque los cálculos nos indicaban que tomaría más de un año en analizar todos esos documentos. Asumíamos que Tree::XPathEngine era intrínsecamente lento, así que habíamos reescrito y usado nuestros propios analizadores usando expresiones regulares. Con el nuevo Perl, analizamos todos los documentos en 2 días. 2 días en lugar de 365.
En vez de quedarme perplejo por todo esto, comencé a enviar el código anterior a varias compañías y proyectos en que había intervenido con el uso de un montón de Perl sobre Redhat o distribuciones derivadas. Resultó que muchos de ellos estaban ejecutando el Perl roto y algunos de ellos habían gastado considerables cantidades de tiempo y dinero en optimizar su código Perl y la infraestructura que lo rodea para mejorar el rendimiento. También resultó que el problema existe en el Perl que viene con Fedora 9, incluso si compilas perl desde el paquete del código fuente de perl en Fedora 9.
Así que... ¡guau! ¿Cuántas personas pueden estar afectadas por esto?
Me dí cuenta que cualquiera que ejecute código Perl con el intérprete perl de una distribución Redhat 5.2, CentOS 5.2 o Fedora 9 es una víctima en potencia. Sí, incluso si tu código no usa el modismo "bless/overload", ¡muchos módulos CPAN lo hacen! Esta búsqueda en Google muestra más de 150 módulos que usan el modismo "bless/overload" y entre ellos están incluidos algunos muy populares como URI o JSON.
De acuerdo a este análisis en Google Trends, Redhat, CentOS y Fedora constituyen la mayoría de las distribuciones Linux usadas en producción. Todas ellas tienen un Perl estropeado. ¿Cuánto tiempo y dinero se ha perdido a causa de esto? Tengo la profunda sensación de que es un número muy alto. Y también tengo la sensación de que muchas personas han cambiado de Perl a Python/Ruby/Java/C debido a que este error les hizo asumir el hecho de que "Perl es lento". Espero que este error sea más publicitado porque, silenciosamente, está matando la reputación de Perl y resultando en un muy grave desperdicio de recursos.
Referencias
* Artículo original
* LiveJournal
* Perl Buzz
* Use Perl. Nicholas da más detalles de este problema conocido desde hace dos años.