blob: 50100613e21b9393993de596177abf032bab7343 [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
16from genshi.builder import tag
17from genshi.template import MarkupTemplate
18
19from jinja import Environment
20
Alexander Schremmer303a7e42007-02-28 22:44:14 +010021try:
22 from django.conf import settings
23 settings.configure()
24 from django.template import Context as DjangoContext
25 from django.template import Template as DjangoTemplate
26 have_django = True
27except ImportError:
28 have_django = False
Armin Ronacherde478f62007-02-28 22:35:04 +010029
Armin Ronachere98c5f52007-04-21 09:39:06 +020030try:
31 from kid import Template as KidTemplate
32 have_kid = True
33except ImportError:
34 have_kid = False
35
Armin Ronacherde478f62007-02-28 22:35:04 +010036from Cheetah.Template import Template as CheetahTemplate
37
Alexander Schremmer303a7e42007-02-28 22:44:14 +010038try:
39 from mako.template import Template as MakoTemplate
40 have_mako = True
41except ImportError:
42 have_mako = False
Armin Ronacherde478f62007-02-28 22:35:04 +010043
Armin Ronacherfb5bebc2007-04-27 18:24:19 +020044table = [dict(zip('abcdefghij', map(unicode,range(1, 11))))
Armin Ronacherde478f62007-02-28 22:35:04 +010045 for x in range(1000)]
46
47genshi_tmpl = MarkupTemplate("""
48<table xmlns:py="http://genshi.edgewall.org/">
49<tr py:for="row in table">
50<td py:for="c in row.values()" py:content="c"/>
51</tr>
52</table>
53""")
54
Armin Ronachere98c5f52007-04-21 09:39:06 +020055if have_kid:
56 kid_tmpl = KidTemplate("""
57<table xmlns:py="http://purl.org/kid/ns#">
58<tr py:for="row in table">
59<td py:for="c in row.values()" py:content="c"/>
60</tr>
61</table>
62""")
63
Alexander Schremmer303a7e42007-02-28 22:44:14 +010064if have_django:
65 django_tmpl = DjangoTemplate("""
Armin Ronacherde478f62007-02-28 22:35:04 +010066<table>
67{% for row in table %}
Armin Ronachere98c5f52007-04-21 09:39:06 +020068<tr>{% for col in row.values %}<td>{{ col }}</td>{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010069{% endfor %}
70</table>
71""")
72
73jinja_tmpl = Environment().from_string('''
74<table>
Armin Ronacher5adf94f2007-03-29 22:11:59 +020075{% for row in table -%}
Armin Ronachere98c5f52007-04-21 09:39:06 +020076<tr>{% for col in row.values() %}<td>{{ col }}</td>{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010077{% endfor %}
78</table>
79''')
80
81cheetah_tmpl = CheetahTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +010082<table>
83#for $row in $table
84<tr>
85#for $col in $row.values()
Armin Ronachere98c5f52007-04-21 09:39:06 +020086<td>$col</td>
Armin Ronacherde478f62007-02-28 22:35:04 +010087#end for
88</tr>
89#end for
90</table>
91''', searchList=[{'table': table, 'escape': cgi.escape}])
92
Alexander Schremmer303a7e42007-02-28 22:44:14 +010093if have_mako:
94 mako_tmpl = MakoTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +010095<table>
96% for row in table:
97<tr>
98% for col in row.values():
Armin Ronachere98c5f52007-04-21 09:39:06 +020099 <td>${col}</td>
Armin Ronacherde478f62007-02-28 22:35:04 +0100100% endfor
101</tr>
102% endfor
103</table>
104''')
105
106def test_django():
107 """Django Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100108 if not have_django:
109 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100110 context = DjangoContext({'table': table})
111 django_tmpl.render(context)
112
113def test_jinja():
114 """Jinja Templates"""
115 jinja_tmpl.render(table=table)
116
117def test_genshi():
118 """Genshi Templates"""
119 stream = genshi_tmpl.generate(table=table)
120 stream.render('html', strip_whitespace=False)
121
Armin Ronachere98c5f52007-04-21 09:39:06 +0200122def test_kid():
123 """Kid Templates"""
124 if not have_kid:
125 return
126 kid_tmpl.table = table
127 kid_tmpl.serialize(output="html")
128
Armin Ronacherde478f62007-02-28 22:35:04 +0100129def test_cheetah():
130 """Cheetah Templates"""
131 cheetah_tmpl.respond()
132
133def test_mako():
134 """Mako Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100135 if not have_mako:
136 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100137 mako_tmpl.render(table=table)
138
139
140def run(which=None, number=10):
Armin Ronachere98c5f52007-04-21 09:39:06 +0200141 tests = ['test_django', 'test_jinja', 'test_kid', 'test_genshi',
142 'test_cheetah', 'test_mako']
Armin Ronacherde478f62007-02-28 22:35:04 +0100143
144 if which:
145 tests = filter(lambda n: n[5:] in which, tests)
146
147 for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
148 t = timeit.Timer(setup='from __main__ import %s;' % test,
149 stmt='%s()' % test)
150 time = t.timeit(number=number) / number
151
152 if time < 0.00001:
153 result = ' (not installed?)'
154 else:
155 result = '%16.2f ms' % (1000 * time)
156 print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
157
158
159if __name__ == '__main__':
160 which = [arg for arg in sys.argv[1:] if arg[0] != '-']
161
162 if '-p' in sys.argv:
Armin Ronacher5adf94f2007-03-29 22:11:59 +0200163 from cProfile import Profile
164 from pstats import Stats
165 p = Profile()
166 p.runcall(test_jinja)
167 stats = Stats(p)
Armin Ronacherde478f62007-02-28 22:35:04 +0100168 stats.strip_dirs()
169 stats.sort_stats('time', 'calls')
170 stats.print_stats()
171 else:
172 run(which)