blob: c86a12a46b71e2aeb9d6e4120ed1abe164e3ccd4 [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
Armin Ronacher1cc232c2007-09-07 17:52:41 +020010import os
Armin Ronacherde478f62007-02-28 22:35:04 +010011import sys
Armin Ronacher1cc232c2007-09-07 17:52:41 +020012sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))
13
14import cgi
Armin Ronacherde478f62007-02-28 22:35:04 +010015import timeit
Armin Ronacher5adf94f2007-03-29 22:11:59 +020016import jdebug
Armin Ronacherde478f62007-02-28 22:35:04 +010017from StringIO import StringIO
18
Armin Ronacher1cc232c2007-09-07 17:52:41 +020019
Armin Ronacherccf284b2007-05-21 16:44:26 +020020try:
21 from genshi.builder import tag
22 from genshi.template import MarkupTemplate
23 have_genshi = True
24except ImportError:
25 have_genshi = False
Armin Ronacherde478f62007-02-28 22:35:04 +010026
Christoph Hacke9e43bb2008-04-13 23:35:48 +020027from jinja2 import Environment
Armin Ronacherde478f62007-02-28 22:35:04 +010028
Alexander Schremmer303a7e42007-02-28 22:44:14 +010029try:
30 from django.conf import settings
31 settings.configure()
32 from django.template import Context as DjangoContext
33 from django.template import Template as DjangoTemplate
34 have_django = True
35except ImportError:
36 have_django = False
Armin Ronacherde478f62007-02-28 22:35:04 +010037
Armin Ronachere98c5f52007-04-21 09:39:06 +020038try:
39 from kid import Template as KidTemplate
40 have_kid = True
41except ImportError:
42 have_kid = False
43
Armin Ronacherccf284b2007-05-21 16:44:26 +020044try:
45 from Cheetah.Template import Template as CheetahTemplate
46 have_cheetah = True
47except ImportError:
48 have_cheetah = False
Armin Ronacherde478f62007-02-28 22:35:04 +010049
Alexander Schremmer303a7e42007-02-28 22:44:14 +010050try:
51 from mako.template import Template as MakoTemplate
52 have_mako = True
53except ImportError:
54 have_mako = False
Armin Ronacherde478f62007-02-28 22:35:04 +010055
Armin Ronacherfb5bebc2007-04-27 18:24:19 +020056table = [dict(zip('abcdefghij', map(unicode,range(1, 11))))
Armin Ronacherde478f62007-02-28 22:35:04 +010057 for x in range(1000)]
58
Armin Ronacherccf284b2007-05-21 16:44:26 +020059if have_genshi:
60 genshi_tmpl = MarkupTemplate("""
Armin Ronacherde478f62007-02-28 22:35:04 +010061<table xmlns:py="http://genshi.edgewall.org/">
62<tr py:for="row in table">
63<td py:for="c in row.values()" py:content="c"/>
64</tr>
65</table>
66""")
67
Armin Ronachere98c5f52007-04-21 09:39:06 +020068if have_kid:
69 kid_tmpl = KidTemplate("""
70<table xmlns:py="http://purl.org/kid/ns#">
71<tr py:for="row in table">
72<td py:for="c in row.values()" py:content="c"/>
73</tr>
74</table>
75""")
76
Alexander Schremmer303a7e42007-02-28 22:44:14 +010077if have_django:
78 django_tmpl = DjangoTemplate("""
Armin Ronacherde478f62007-02-28 22:35:04 +010079<table>
80{% for row in table %}
Armin Ronachere98c5f52007-04-21 09:39:06 +020081<tr>{% for col in row.values %}<td>{{ col }}</td>{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010082{% endfor %}
83</table>
84""")
85
86jinja_tmpl = Environment().from_string('''
87<table>
Armin Ronacher5adf94f2007-03-29 22:11:59 +020088{% for row in table -%}
Armin Ronachere98c5f52007-04-21 09:39:06 +020089<tr>{% for col in row.values() %}<td>{{ col }}</td>{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010090{% endfor %}
91</table>
92''')
93
Armin Ronacherccf284b2007-05-21 16:44:26 +020094if have_cheetah:
95 cheetah_tmpl = CheetahTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +010096<table>
97#for $row in $table
98<tr>
99#for $col in $row.values()
Armin Ronachere98c5f52007-04-21 09:39:06 +0200100<td>$col</td>
Armin Ronacherde478f62007-02-28 22:35:04 +0100101#end for
102</tr>
103#end for
104</table>
105''', searchList=[{'table': table, 'escape': cgi.escape}])
106
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100107if have_mako:
108 mako_tmpl = MakoTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +0100109<table>
110% for row in table:
111<tr>
112% for col in row.values():
Armin Ronachere98c5f52007-04-21 09:39:06 +0200113 <td>${col}</td>
Armin Ronacherde478f62007-02-28 22:35:04 +0100114% endfor
115</tr>
116% endfor
117</table>
118''')
119
120def test_django():
121 """Django Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100122 if not have_django:
123 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100124 context = DjangoContext({'table': table})
125 django_tmpl.render(context)
126
127def test_jinja():
128 """Jinja Templates"""
129 jinja_tmpl.render(table=table)
130
131def test_genshi():
132 """Genshi Templates"""
Armin Ronacherccf284b2007-05-21 16:44:26 +0200133 if not have_genshi:
134 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100135 stream = genshi_tmpl.generate(table=table)
136 stream.render('html', strip_whitespace=False)
137
Armin Ronachere98c5f52007-04-21 09:39:06 +0200138def test_kid():
139 """Kid Templates"""
140 if not have_kid:
141 return
142 kid_tmpl.table = table
143 kid_tmpl.serialize(output="html")
144
Armin Ronacherde478f62007-02-28 22:35:04 +0100145def test_cheetah():
146 """Cheetah Templates"""
Armin Ronacherccf284b2007-05-21 16:44:26 +0200147 if not have_cheetah:
148 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100149 cheetah_tmpl.respond()
150
151def test_mako():
152 """Mako Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100153 if not have_mako:
154 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100155 mako_tmpl.render(table=table)
156
157
158def run(which=None, number=10):
Armin Ronachere98c5f52007-04-21 09:39:06 +0200159 tests = ['test_django', 'test_jinja', 'test_kid', 'test_genshi',
160 'test_cheetah', 'test_mako']
Armin Ronacherde478f62007-02-28 22:35:04 +0100161
162 if which:
163 tests = filter(lambda n: n[5:] in which, tests)
164
165 for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
166 t = timeit.Timer(setup='from __main__ import %s;' % test,
167 stmt='%s()' % test)
168 time = t.timeit(number=number) / number
169
170 if time < 0.00001:
171 result = ' (not installed?)'
172 else:
173 result = '%16.2f ms' % (1000 * time)
174 print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
175
176
177if __name__ == '__main__':
178 which = [arg for arg in sys.argv[1:] if arg[0] != '-']
179
180 if '-p' in sys.argv:
Armin Ronacher5adf94f2007-03-29 22:11:59 +0200181 from cProfile import Profile
182 from pstats import Stats
183 p = Profile()
184 p.runcall(test_jinja)
185 stats = Stats(p)
Armin Ronacherde478f62007-02-28 22:35:04 +0100186 stats.strip_dirs()
187 stats.sort_stats('time', 'calls')
188 stats.print_stats()
189 else:
190 run(which)