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
- 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).
- b1_tpl: El mismo resultado que el anterior pero llamándose al generador de plantilla para cada iteración.
- 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 %}
- 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» }}).
- 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 |