blob: a7deaff279b0648fd17db9db5121e5df18e5f502 [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
30from Cheetah.Template import Template as CheetahTemplate
31
Alexander Schremmer303a7e42007-02-28 22:44:14 +010032try:
33 from mako.template import Template as MakoTemplate
34 have_mako = True
35except ImportError:
36 have_mako = False
Armin Ronacherde478f62007-02-28 22:35:04 +010037
38table = [dict(a='1',b='2',c='3',d='4',e='5',f='6',g='7',h='8',i='9',j='10')
39 for x in range(1000)]
40
41genshi_tmpl = MarkupTemplate("""
42<table xmlns:py="http://genshi.edgewall.org/">
43<tr py:for="row in table">
44<td py:for="c in row.values()" py:content="c"/>
45</tr>
46</table>
47""")
48
Alexander Schremmer303a7e42007-02-28 22:44:14 +010049if have_django:
50 django_tmpl = DjangoTemplate("""
Armin Ronacherde478f62007-02-28 22:35:04 +010051<table>
52{% for row in table %}
Armin Ronacher5adf94f2007-03-29 22:11:59 +020053<tr>{% for col in row.values %}{{ col }}{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010054{% endfor %}
55</table>
56""")
57
58jinja_tmpl = Environment().from_string('''
59<table>
Armin Ronacher5adf94f2007-03-29 22:11:59 +020060{% for row in table -%}
61<tr>{% for col in row.values() %}{{ col }}{% endfor %}</tr>
Armin Ronacherde478f62007-02-28 22:35:04 +010062{% endfor %}
63</table>
64''')
65
66cheetah_tmpl = CheetahTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +010067<table>
68#for $row in $table
69<tr>
70#for $col in $row.values()
71$col
72#end for
73</tr>
74#end for
75</table>
76''', searchList=[{'table': table, 'escape': cgi.escape}])
77
Alexander Schremmer303a7e42007-02-28 22:44:14 +010078if have_mako:
79 mako_tmpl = MakoTemplate('''
Armin Ronacherde478f62007-02-28 22:35:04 +010080<table>
81% for row in table:
82<tr>
83% for col in row.values():
Armin Ronacher5adf94f2007-03-29 22:11:59 +020084 ${col}
Armin Ronacherde478f62007-02-28 22:35:04 +010085% endfor
86</tr>
87% endfor
88</table>
89''')
90
91def test_django():
92 """Django Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +010093 if not have_django:
94 return
Armin Ronacherde478f62007-02-28 22:35:04 +010095 context = DjangoContext({'table': table})
96 django_tmpl.render(context)
97
98def test_jinja():
99 """Jinja Templates"""
100 jinja_tmpl.render(table=table)
101
102def test_genshi():
103 """Genshi Templates"""
104 stream = genshi_tmpl.generate(table=table)
105 stream.render('html', strip_whitespace=False)
106
107def test_cheetah():
108 """Cheetah Templates"""
109 cheetah_tmpl.respond()
110
111def test_mako():
112 """Mako Templates"""
Alexander Schremmer303a7e42007-02-28 22:44:14 +0100113 if not have_mako:
114 return
Armin Ronacherde478f62007-02-28 22:35:04 +0100115 mako_tmpl.render(table=table)
116
117
118def run(which=None, number=10):
119 tests = ['test_django', 'test_jinja', 'test_genshi', 'test_cheetah', 'test_mako']
120
121 if which:
122 tests = filter(lambda n: n[5:] in which, tests)
123
124 for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
125 t = timeit.Timer(setup='from __main__ import %s;' % test,
126 stmt='%s()' % test)
127 time = t.timeit(number=number) / number
128
129 if time < 0.00001:
130 result = ' (not installed?)'
131 else:
132 result = '%16.2f ms' % (1000 * time)
133 print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
134
135
136if __name__ == '__main__':
137 which = [arg for arg in sys.argv[1:] if arg[0] != '-']
138
139 if '-p' in sys.argv:
Armin Ronacher5adf94f2007-03-29 22:11:59 +0200140 from cProfile import Profile
141 from pstats import Stats
142 p = Profile()
143 p.runcall(test_jinja)
144 stats = Stats(p)
Armin Ronacherde478f62007-02-28 22:35:04 +0100145 stats.strip_dirs()
146 stats.sort_stats('time', 'calls')
147 stats.print_stats()
148 else:
149 run(which)