El Blog de Trespams

Blog personal sobre tecnologia, gestió de projectes i coses que se me passen pel cap

Benchmark: mako i lmxl

Estam plantejant fer una remodelació de la web B2B que tenim, ara està feta en Java i aprofitant la remodelació la meva intenció ( si me deixen clar), és aprofitar que la remodelació és força important per a reescriure el codi en Python i Django. Si fos un canvi petit no m'ho plantejaria, però és un canvi que pot dur mesos de feina i en aquest cas refer-ho amb Python suposa no allargar els temps de desenvolupament, encara que la feina global en termes de funcionalitat sigui més gran.

Però tampoc és cosa de tirar-se a la piscina, i abans de res convé saber amb què ens trobarem. Un dels aspectes més crítics és que hem de consumir un servei web en format xml sobre http. Cap problema, urllib per exemple és capaç de fer tot això i molt més, la cosa està en poder generar els xml i consumir-los en molt poc temps.

Aquest cap de setmana m'he entretingut fent un petit benchmark [1], volia comprovar una hipòtesis: fer servir un llenguatge de plantilles per generar les peticions xml i un parsejador per a consumir l'xml que m'arribarà. L'altra opció es generar les peticions directament amb la llibreria de parseig.

La primera opció té com avantatges que s'ha d'escriure menys codi i que queda força documentada la petició en sí. La segona te l'avantatge de que que sols fas servir una llibreria. Així doncs el que ha de dir la darrera paraula és el factor rapidesa. Serà més ràpida la llibreria de plantilles o la de l'xml?

Primer presentarem els candidats: per una part mako, un llenguatge de plantilles que surt molt ben parat a les comparatives de velocitat i de l'altra lxml una interfície Python damunt unes de les llibreries per tractar xml més ràpides del mercat libxml2 i libxslt.

Per fer les proves tirarem de les dades que representen els cotxes que he tingut:

VEHICLES = {'seat': {'id': 1, 'color':'blanc', 'preu':150000}, 'ax' : {'id': 2, 'color':'blanc', 'preu':1100000}, '505' : {'id': 3, 'color':'blanc', 'preu': 500}, 'saxo': {'id': 4, 'color':'blau', 'preu':1500000} }

El que farem és generar un xml que representi aquesta estructura de dades. Com que tant amb mako com lxml la cosa va força ràpida, farem 10.000 repeticions.

El codi per mako és

from mako.template import Template

template = """ % for marca, desc in vehicles.items(): ${marca} ${desc['color']} ${desc['preu']} % endfor """
plantilla = Template(template)
for i in xrange(1, REPETICIONS):
xml = plantilla.render(vehicles=VEHICLES)

El que feim és compilar la plantilla un pic, per simular les condicions reals, ja que en una aplicació en producció és el que faríem, i renderitxar l'xml amb les dades fins al nombre de repeticions desitjat.

Per lxml la cosa és semblant, sols que el codi (si no tenim en compte la definició de la plantilla) és una mica més llarg

from lxml import etree

for i in xrange(1, REPETICIONS):
root = etree.Element('vehicles')
for marca_vehiculo, desc in VEHICLES.items():
vehicle = etree.SubElement(root, 'vehicle', id=str(desc['id']))
marca = etree.SubElement(vehicle, "marca")
marca.text = marca_vehiculo
color = etree.SubElement(vehicle, "color")
color.text = desc['color']
preu = etree.SubElement(vehicle, 'preu')
preu.text = "%.0f" % desc['preu']
xml2 = etree.tostring(root, pretty_print=False)

També en aquest cas procuram que hi hagi igualtat de condicions, i hem posat el pretty_print a False de manera que l'xml generat no estarà ben tabulat i no quedarà tan elegant com el el cas de mako, però també és el que faríem en un entorn de producció.

I ja està, ara sols falta executar-ho i mostrar-ne els resultats:

Repeticionsmakolxml 1000,0761 s0.0277 s 1.0000,2897 s0.2823 s 10.0002.3076 s2.8906 s

D'això en treim dues conclusions:

  • Que ambdues aproximacions són molt ràpides en la generació de l'xml.
  • Que mako s'aprofita molt bé de la precompilació de les plantilles. En el benchmark he considerat que es compilava un pic i després s'executaven les repeticions. Si no consideram el temps de compilació

Repeticionsmakolxml 1000,0201 s0.0277 s 1.0000,2079 s0.2750 s 10.0001,9888 s2.9513 s

És a dir, que si feim sempre feina amb el mateix tipus de peticions, l'opció de fer servir mako per a generar les peticions xml, compilant les plantilles a l'inici de l'aplicació és té un rendiment molt millor que generant l'xml cada cop amb l'lxml.

Per cert, les proves estan fetes amb Ubuntu Linux corrent en un PowerPC de doble processador de 2 GHz, és a dir, res de l'altre mon.

[1] Sí, ja ho sé, no m'hauria d'endur feina a casa

blog comments powered by Disqus