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