cmlenz@97: # -*- encoding: utf-8 -*- cmlenz@97: # Template language benchmarks cmlenz@97: # cmlenz@97: # Objective: Generate a 1000x10 HTML table as fast as possible. cmlenz@97: # cmlenz@97: # Author: Jonas Borgström cmlenz@97: cmlenz@117: import cgi cmlenz@97: import sys cmlenz@97: import timeit cmlenz@319: from StringIO import StringIO cmlenz@230: from genshi.builder import tag cmlenz@592: from genshi.template import MarkupTemplate, NewTextTemplate cmlenz@97: cmlenz@130: try: cmlenz@332: from elementtree import ElementTree as et cmlenz@332: except ImportError: cmlenz@332: et = None cmlenz@332: cmlenz@332: try: cmlenz@332: import cElementTree as cet cmlenz@332: except ImportError: cmlenz@332: cet = None cmlenz@332: cmlenz@332: try: cmlenz@130: import neo_cgi, neo_cs, neo_util cmlenz@130: except ImportError: cmlenz@130: neo_cgi = None cmlenz@130: cmlenz@130: try: cmlenz@130: import kid cmlenz@130: except ImportError: cmlenz@130: kid = None cmlenz@130: cmlenz@130: try: cmlenz@130: from django.conf import settings cmlenz@130: settings.configure() cmlenz@130: from django.template import Context as DjangoContext cmlenz@130: from django.template import Template as DjangoTemplate cmlenz@130: except ImportError: cmlenz@130: DjangoContext = DjangoTemplate = None cmlenz@130: cmlenz@319: try: cmlenz@543: from mako.template import Template as MakoTemplate cmlenz@319: except ImportError: cmlenz@543: MakoTemplate = None cmlenz@319: cmlenz@97: table = [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) cmlenz@97: for x in range(1000)] cmlenz@97: cmlenz@233: genshi_tmpl = MarkupTemplate(""" cmlenz@230: cmlenz@97: cmlenz@97: cmlenz@97:
cmlenz@97:
cmlenz@97: """) cmlenz@97: cmlenz@233: genshi_tmpl2 = MarkupTemplate(""" cmlenz@230: $table
cmlenz@97: """) cmlenz@97: cmlenz@592: genshi_text_tmpl = NewTextTemplate(""" cmlenz@592: cmlenz@592: {% for row in table %} cmlenz@592: {% for c in row.values() %}{% end %} cmlenz@592: {% end %} cmlenz@592:
$c
cmlenz@592: """) cmlenz@592: cmlenz@130: if DjangoTemplate: cmlenz@130: django_tmpl = DjangoTemplate(""" cmlenz@130: cmlenz@130: {% for row in table %} cmlenz@130: {% for col in row.values %}{{ col|escape }}{% endfor %} cmlenz@130: {% endfor %} cmlenz@130:
cmlenz@130: """) cmlenz@97: cmlenz@130: def test_django(): cmlenz@130: """Djange template""" cmlenz@130: context = DjangoContext({'table': table}) cmlenz@130: django_tmpl.render(context) cmlenz@97: cmlenz@543: if MakoTemplate: cmlenz@543: mako_tmpl = MakoTemplate(""" cmlenz@319: cmlenz@543: % for row in table: cmlenz@543: cmlenz@543: % for col in row.values(): cmlenz@543: cmlenz@543: % endfor cmlenz@543: cmlenz@543: % endfor cmlenz@319:
${ col | h }
cmlenz@319: """) cmlenz@543: def test_mako(): cmlenz@543: """Mako Template""" cmlenz@543: mako_tmpl.render(table=table) cmlenz@319: cmlenz@230: def test_genshi(): cmlenz@230: """Genshi template""" cmlenz@230: stream = genshi_tmpl.generate(table=table) cmlenz@123: stream.render('html', strip_whitespace=False) cmlenz@97: cmlenz@592: def test_genshi_text(): cmlenz@592: """Genshi text template""" cmlenz@592: stream = genshi_text_tmpl.generate(table=table) cmlenz@592: stream.render('text') cmlenz@592: cmlenz@230: def test_genshi_builder(): cmlenz@230: """Genshi template + tag builder""" cmlenz@97: stream = tag.TABLE([ cmlenz@97: tag.tr([tag.td(c) for c in row.values()]) cmlenz@97: for row in table cmlenz@97: ]).generate() cmlenz@230: stream = genshi_tmpl2.generate(table=stream) cmlenz@123: stream.render('html', strip_whitespace=False) cmlenz@97: cmlenz@97: def test_builder(): cmlenz@230: """Genshi tag builder""" cmlenz@97: stream = tag.TABLE([ cmlenz@97: tag.tr([ cmlenz@97: tag.td(c) for c in row.values() cmlenz@97: ]) cmlenz@97: for row in table cmlenz@97: ]).generate() cmlenz@123: stream.render('html', strip_whitespace=False) cmlenz@97: cmlenz@130: if kid: cmlenz@130: kid_tmpl = kid.Template(""" cmlenz@130: cmlenz@130: cmlenz@130: cmlenz@130:
cmlenz@130:
cmlenz@130: """) cmlenz@97: cmlenz@130: kid_tmpl2 = kid.Template(""" cmlenz@130: $table cmlenz@130: """) cmlenz@130: cmlenz@130: def test_kid(): cmlenz@130: """Kid template""" cmlenz@130: kid_tmpl.table = table cmlenz@130: kid_tmpl.serialize(output='html') cmlenz@130: cmlenz@332: if cet: cmlenz@332: def test_kid_et(): cmlenz@332: """Kid template + cElementTree""" cmlenz@332: _table = cet.Element('table') cmlenz@332: for row in table: cmlenz@332: td = cet.SubElement(_table, 'tr') cmlenz@332: for c in row.values(): cmlenz@332: cet.SubElement(td, 'td').text=str(c) cmlenz@332: kid_tmpl2.table = _table cmlenz@332: kid_tmpl2.serialize(output='html') cmlenz@332: cmlenz@332: if et: cmlenz@332: def test_et(): cmlenz@332: """ElementTree""" cmlenz@332: _table = et.Element('table') cmlenz@332: for row in table: cmlenz@332: tr = et.SubElement(_table, 'tr') cmlenz@332: for c in row.values(): cmlenz@332: et.SubElement(tr, 'td').text=str(c) cmlenz@332: et.tostring(_table) cmlenz@332: cmlenz@332: if cet: cmlenz@332: def test_cet(): cmlenz@332: """cElementTree""" cmlenz@130: _table = cet.Element('table') cmlenz@130: for row in table: cmlenz@332: tr = cet.SubElement(_table, 'tr') cmlenz@130: for c in row.values(): cmlenz@332: cet.SubElement(tr, 'td').text=str(c) cmlenz@332: cet.tostring(_table) cmlenz@97: cmlenz@130: if neo_cgi: cmlenz@130: def test_clearsilver(): cmlenz@130: """ClearSilver""" cmlenz@130: hdf = neo_util.HDF() cmlenz@130: for i, row in enumerate(table): cmlenz@130: for j, c in enumerate(row.values()): cmlenz@130: hdf.setValue("rows.%d.cell.%d" % (i, j), cgi.escape(str(c))) cmlenz@97: cmlenz@130: cs = neo_cs.CS(hdf) cmlenz@130: cs.parseStr(""" cmlenz@97: cmlenz@97:
""") cmlenz@130: cs.render() cmlenz@97: cmlenz@97: cmlenz@97: def run(which=None, number=10): cmlenz@592: tests = ['test_builder', 'test_genshi', 'test_genshi_text', cmlenz@592: 'test_genshi_builder', 'test_mako', 'test_kid', 'test_kid_et', cmlenz@592: 'test_et', 'test_cet', 'test_clearsilver', 'test_django'] cmlenz@319: cmlenz@97: if which: cmlenz@97: tests = filter(lambda n: n[5:] in which, tests) cmlenz@97: cmlenz@130: for test in [t for t in tests if hasattr(sys.modules[__name__], t)]: cmlenz@97: t = timeit.Timer(setup='from __main__ import %s;' % test, cmlenz@97: stmt='%s()' % test) cmlenz@97: time = t.timeit(number=number) / number cmlenz@97: cmlenz@130: if time < 0.00001: cmlenz@130: result = ' (not installed?)' cmlenz@130: else: cmlenz@130: result = '%16.2f ms' % (1000 * time) cmlenz@130: print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result) cmlenz@97: cmlenz@97: cmlenz@97: if __name__ == '__main__': cmlenz@97: which = [arg for arg in sys.argv[1:] if arg[0] != '-'] cmlenz@97: cmlenz@97: if '-p' in sys.argv: cmlenz@815: import cProfile, pstats cmlenz@815: prof = cProfile.Profile() cmlenz@815: prof.run('run(%r, number=1)' % which) cmlenz@815: stats = pstats.Stats(prof) cmlenz@97: stats.strip_dirs() cmlenz@97: stats.sort_stats('time', 'calls') cmlenz@815: stats.print_stats(25) cmlenz@815: if '-v' in sys.argv: cmlenz@815: stats.print_callees() cmlenz@815: stats.print_callers() cmlenz@97: else: cmlenz@97: run(which)