Etiquetas

,

En mi apunte anterior conté que habíamos desarrollado y liberado Haanga, el sistema de plantillas de Menéame. Ahora acabo de hacer unos benchmarks comparándolo con Django y H2O. La intención fue medir el rendimiento del motor de plantillas de cada uno.

Los resultados se muestran en la tabla a continuación. La primera columna es el tipo de benchmark. La segunda, tercera y cuarta son el número de conexiones por segundo (más altas son mejores) de cada uno de los sistemas. Las dos últimas columnas indican cuantas veces más conexiones por segundo sirvió Haanga.

Bench Haanga Django H2O vs Django vs H2O
b1 (sin plantillas) 3214.84 769.48 1447.68 4.2 2.2
b1_tpl 1031.57 203.28 273.24 5.1 3.8
b2_tpl 1944.41 270.96 240.55 7.2 8.1
b2_filters 1011.10 65.14 156.68 15.5 6.5
header 2365.59 185.69 273.61 12.7 8.6

Haanga saca mucha diferencia a los dos sistemas en cualquiera de las pruebas.

Explicación de los benchmarks

  1. b1 sin plantillas: Este es un programa simple que sólo ejecuta un bucle para imprimir la hora cien veces. No se usan templates, pero sirve para dar una referencia y notar la diferencia entre la inclusión de librerías entre Haanga y H2O (en la vistas de Django ya se incluyen).
  2. b1_tpl: El mismo resultado que el anterior pero llamándose al generador de plantilla para cada iteración.
  3. b2_tpl: Este es un caso más habitual. En vez de llamar cien veces al generador se guardan los resultados en un array y al final se genera el resultado desde el template (con el {% for o in objects %}
  4. b2_filters: Es el mismo programa que el anterior pero al template se le agregaron un par de filtros (La hora ({{ o.i|escape }}) en epochs es: {{o.epoch}} ({{ o.epoch|date:”r” }}).
  5. header: Este es un caso más real. Tomé una de las plantillas más complejas que usamos en Menéame,  la que genera la cabecera HTML, logo y menú superior (header.html). Eliminé las etiquetas no compatibles con los otros dos (los exec y trans), se llama tres veces al generador de plantillas (me aseguré que el HTML era similar en los tres –había diferencia en los espacios en blanco que genera cada uno–).

Los códigos fuentes completos lo podéis bajar en un tgz.

Ejecución

Todas las pruebas fueron hechas sobre un Intel Quad de 2.40GHz con 4GB de RAM. No había otros procesos consumiendo CPU.

Los números de conexiones por segundo fueron obtenidos con el Apache Benchmark contra el servidor local (localhost). El comando fue «ab -q -S -c 2 -t 30 $url», podéis ver el script benchs.sh en el tgz mencionado antes.

Los PHP se ejecutaron en un Apache2 estándar de Ubuntu 10.4, con el PHP5 también estándar, el xcache (con su configuración por defecto). El único cambio que hice fue en la configuración del PHP5 (php.ini) para que sólo avise de errores (i.e. «error_reporting = E_ERROR»).

El Apache con el mod_python me daba resultados muy malos con el Apache 2, así que consulté a Antoni Aloy (un expertísimo en Django) y me recomendó hacerlo con el gunicorn. Este es el comando que utilicé: «python manage.py run_gunicorn -w 5» (el DEBUG del Django estaba deshabilitado).

Actualización: hice las pruebas como me indicó @Rolando con el tornado y su sistema de templates. Estos son los resultados.

Bench Tornado
b1 (sin plantillas) 2988.29
b1_tpl 1111.82
b2_tpl 1802.91
b2_filters 613.54
header 2425.91