blob: b1576df39b6ac649145ec1ec6f95f0a40db57ce8 [file] [log] [blame]
Armin Ronachered03db52007-02-28 22:39:44 +01001# -*- coding: utf-8 -*_
Armin Ronacherde478f62007-02-28 22:35:04 +01002# Template language benchmarks
3#
4# Objective: Generate a 1000x10 HTML table as fast as possible.
5# adapted for jinja 1
6#
7# Author: Jonas Borgström <jonas@edgewall.com>
8# Author: Armin Ronacher <armin.ronacher@active-4.com>
9
10import cgi
11import sys
12import timeit
Armin Ronacher5adf94f2007-03-29 22:11:59 +020013import jdebug
Armin Ronacherde478f62007-02-28 22:35:04 +010014from StringIO import StringIO
15
Armin Ronacherccf284b2007-05-21 16:44:26 +020016try:
17 from genshi.builder import tag
18 from genshi.template import MarkupTemplate
19 have_genshi = True
20except ImportError:
21 have_genshi = False
Armin Ronacherde478f62007-02-28 22:35:04 +010022
23from jinja import Environment
24
Alexander Schremmer303a7e42007-02-28 22:44:14 +010025try:
26 from django.conf import settings
27 settings.configure()
28 from django.template import Context as DjangoContext
29 from django.template import Template as DjangoTemplate
30 have_django = True
31except ImportError:
32 have_django = False
Armin Ronacherde478f62007-02-28 22:35:04 +010033
Armin Ronachere98c5f52007-04-21 09:39:06 +020034try:
35 from kid import Template as KidTemplate
36 have_kid = True
37except ImportError:
38 have_kid = False
39
Armin Ronacherccf284b2007-05-21 16:44:26 +020040try:
41 from Cheetah.Template import Template as CheetahTemplate
42 have_cheetah = True
43except ImportError:
44 have_cheetah = False
Armin Ronacherde478f62007-02-28 22:35:04 +010045
Alexander Schremmer303a7e42007-02-28 22:44:14 +010046try:
47 from mako.template import Template as MakoTemplate
48 have_mako = True
49except ImportError:
50 have_mako = False
Armin Ronacherde478f62007-02-28 22:35:04 +010051
Armin Ronacherfb5bebc2007-04-27 18:24:19 +020052table = [dict(zip('abcdefghij', map(unicode,range(1, 11))))
Armin Ronacherde478f62007-02-28 22:35:04 +010053 for x in range(1000)]
54
Armin Ronacherccf284b2007-05-21 16:44:26 +020055if have_genshi:
56 genshi_tmpl = MarkupTemplate("""
Armin Ronacherde478f62007-02-28 22:35:04 +010057<table xmlns:py="http://genshi.edgewall.org/">
58<tr py:for="row in table">
59<td py:for="c in row.values()" py:content="c"/>
60</tr>
61</table>
62""")
63
Armin Ronachere98c5f52007-04-21 09:39:06 +020064if have_kid:
65 kid_tmpl = KidTemplate("""
66<table xmlns:py="http://purl.org/kid/ns#">
67<tr py:for="row in table">
68<td py:for="c in row.values()" py:content="c"/>
69</tr>
70</table>
71""")
72
Alexander Schremmer303a7e42007-02-28 22:44:14 +010073if have_django:
74 django_tmpl = DjangoTemplate("""
Armin Ronacherde478f62007-02-28 22:35:04 +010075<table>
76{% for row in table %}
Armin Ronachere98c5f52007-04-21 09:39:06 +020077<tr>{% for col in row.values %}<td>{{ col }}</td>{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010078{% endfor %}
79</table>
80""")
81
82jinja_tmpl = Environment().from_string('''
83<table>
Armin Ronacher5adf94f2007-03-29 22:11:59 +020084{% for row in table -%}
Armin Ronachere98c5f52007-04-21 09:39:06 +020085<tr>{% for col in row.values() %}<td>{{ col }}</td>{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010086{% endfor %}
87</table>
88''')
89
Armin Ronacherccf284b2007-05-21 16:44:26 +020090if have_cheetah:
91 cheetah_tmpl = CheetahTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +010092<table>
93#for $row in $table
94<tr>
95#for $col in $row.values()
Armin Ronachere98c5f52007-04-21 09:39:06 +020096<td>$col</td>
Armin Ronacherde478f62007-02-28 22:35:04 +010097#end for
98</tr>
99#end for
100</table>
101''', searchList=[{'table': table, 'escape': cgi.escape}])
102
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100103if have_mako:
104 mako_tmpl = MakoTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +0100105<table>
106% for row in table:
107<tr>
108% for col in row.values():
Armin Ronachere98c5f52007-04-21 09:39:06 +0200109 <td>${col}</td>
Armin Ronacherde478f62007-02-28 22:35:04 +0100110% endfor
111</tr>
112% endfor
113</table>
114''')
115
116def test_django():
117 """Django Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100118 if not have_django:
119 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100120 context = DjangoContext({'table': table})
121 django_tmpl.render(context)
122
123def test_jinja():
124 """Jinja Templates"""
125 jinja_tmpl.render(table=table)
126
127def test_genshi():
128 """Genshi Templates"""
Armin Ronacherccf284b2007-05-21 16:44:26 +0200129 if not have_genshi:
130 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100131 stream = genshi_tmpl.generate(table=table)
132 stream.render('html', strip_whitespace=False)
133
Armin Ronachere98c5f52007-04-21 09:39:06 +0200134def test_kid():
135 """Kid Templates"""
136 if not have_kid:
137 return
138 kid_tmpl.table = table
139 kid_tmpl.serialize(output="html")
140
Armin Ronacherde478f62007-02-28 22:35:04 +0100141def test_cheetah():
142 """Cheetah Templates"""
Armin Ronacherccf284b2007-05-21 16:44:26 +0200143 if not have_cheetah:
144 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100145 cheetah_tmpl.respond()
146
147def test_mako():
148 """Mako Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100149 if not have_mako:
150 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100151 mako_tmpl.render(table=table)
152
153
154def run(which=None, number=10):
Armin Ronachere98c5f52007-04-21 09:39:06 +0200155 tests = ['test_django', 'test_jinja', 'test_kid', 'test_genshi',
156 'test_cheetah', 'test_mako']
Armin Ronacherde478f62007-02-28 22:35:04 +0100157
158 if which:
159 tests = filter(lambda n: n[5:] in which, tests)
160
161 for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
162 t = timeit.Timer(setup='from __main__ import %s;' % test,
163 stmt='%s()' % test)
164 time = t.timeit(number=number) / number
165
166 if time < 0.00001:
167 result = ' (not installed?)'
168 else:
169 result = '%16.2f ms' % (1000 * time)
170 print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
171
172
173if __name__ == '__main__':
174 which = [arg for arg in sys.argv[1:] if arg[0] != '-']
175
176 if '-p' in sys.argv:
Armin Ronacher5adf94f2007-03-29 22:11:59 +0200177 from cProfile import Profile
178 from pstats import Stats
179 p = Profile()
180 p.runcall(test_jinja)
181 stats = Stats(p)
Armin Ronacherde478f62007-02-28 22:35:04 +0100182 stats.strip_dirs()
183 stats.sort_stats('time', 'calls')
184 stats.print_stats()
185 else:
186 run(which)