blob: 01c188b2dc10560289bcd2027f3de008e7d94bdf [file] [log] [blame]
Armin Ronacherde478f62007-02-28 22:35:04 +01001# Template language benchmarks
2#
3# Objective: Generate a 1000x10 HTML table as fast as possible.
4# adapted for jinja 1
5#
6# Author: Jonas Borgström <jonas@edgewall.com>
7# Author: Armin Ronacher <armin.ronacher@active-4.com>
8
9import cgi
10import sys
11import timeit
12from StringIO import StringIO
13
14from genshi.builder import tag
15from genshi.template import MarkupTemplate
16
17from jinja import Environment
18
19from django.conf import settings
20settings.configure()
21from django.template import Context as DjangoContext
22from django.template import Template as DjangoTemplate
23
24from Cheetah.Template import Template as CheetahTemplate
25
26from mako.template import Template as MakoTemplate
27
28table = [dict(a='1',b='2',c='3',d='4',e='5',f='6',g='7',h='8',i='9',j='10')
29 for x in range(1000)]
30
31genshi_tmpl = MarkupTemplate("""
32<table xmlns:py="http://genshi.edgewall.org/">
33<tr py:for="row in table">
34<td py:for="c in row.values()" py:content="c"/>
35</tr>
36</table>
37""")
38
39django_tmpl = DjangoTemplate("""
40<table>
41{% for row in table %}
42<tr>{% for col in row.values %}{{ col|escape }}{% endfor %}</tr>
43{% endfor %}
44</table>
45""")
46
47jinja_tmpl = Environment().from_string('''
48<table>
49{% for row in table %}
50<tr>{% for col in row.values() %}{{ col|escape }}{% endfor %}</tr>
51{% endfor %}
52</table>
53''')
54
55cheetah_tmpl = CheetahTemplate('''
56# filter escape
57<table>
58#for $row in $table
59<tr>
60#for $col in $row.values()
61$col
62#end for
63</tr>
64#end for
65</table>
66''', searchList=[{'table': table, 'escape': cgi.escape}])
67
68mako_tmpl = MakoTemplate('''
69<table>
70% for row in table:
71<tr>
72% for col in row.values():
73 ${col|h}
74% endfor
75</tr>
76% endfor
77</table>
78''')
79
80def test_django():
81 """Django Templates"""
82 context = DjangoContext({'table': table})
83 django_tmpl.render(context)
84
85def test_jinja():
86 """Jinja Templates"""
87 jinja_tmpl.render(table=table)
88
89def test_genshi():
90 """Genshi Templates"""
91 stream = genshi_tmpl.generate(table=table)
92 stream.render('html', strip_whitespace=False)
93
94def test_cheetah():
95 """Cheetah Templates"""
96 cheetah_tmpl.respond()
97
98def test_mako():
99 """Mako Templates"""
100 mako_tmpl.render(table=table)
101
102
103def run(which=None, number=10):
104 tests = ['test_django', 'test_jinja', 'test_genshi', 'test_cheetah', 'test_mako']
105
106 if which:
107 tests = filter(lambda n: n[5:] in which, tests)
108
109 for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
110 t = timeit.Timer(setup='from __main__ import %s;' % test,
111 stmt='%s()' % test)
112 time = t.timeit(number=number) / number
113
114 if time < 0.00001:
115 result = ' (not installed?)'
116 else:
117 result = '%16.2f ms' % (1000 * time)
118 print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
119
120
121if __name__ == '__main__':
122 which = [arg for arg in sys.argv[1:] if arg[0] != '-']
123
124 if '-p' in sys.argv:
125 import hotshot, hotshot.stats
126 prof = hotshot.Profile("template.prof")
127 benchtime = prof.runcall(run, which, number=1)
128 stats = hotshot.stats.load("template.prof")
129 stats.strip_dirs()
130 stats.sort_stats('time', 'calls')
131 stats.print_stats()
132 else:
133 run(which)