Edgewall Software

source: trunk/examples/bench/bigtable.py

Last change on this file was 1017, checked in by cmlenz, 15 years ago

Switch profiling in the benchmarks to cProfile.

  • Property svn:eol-style set to native
File size: 5.9 KB
Line 
1# -*- encoding: utf-8 -*-
2# Template language benchmarks
3#
4# Objective: Generate a 1000x10 HTML table as fast as possible.
5#
6# Author: Jonas Borgström <jonas@edgewall.com>
7
8import cgi
9import sys
10import timeit
11from StringIO import StringIO
12from genshi.builder import tag
13from genshi.template import MarkupTemplate, NewTextTemplate
14
15try:
16    from elementtree import ElementTree as et
17except ImportError:
18    et = None
19
20try:
21    import cElementTree as cet
22except ImportError:
23    cet = None
24
25try:
26    import neo_cgi, neo_cs, neo_util
27except ImportError:
28    neo_cgi = None
29
30try:
31    import kid
32except ImportError:
33    kid = None
34
35try:
36    from django.conf import settings
37    settings.configure()
38    from django.template import Context as DjangoContext
39    from django.template import Template as DjangoTemplate
40except ImportError:
41    DjangoContext = DjangoTemplate = None
42
43try:
44    from mako.template import Template as MakoTemplate
45except ImportError:
46    MakoTemplate = None
47
48table = [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10)
49          for x in range(1000)]
50
51genshi_tmpl = MarkupTemplate("""
52<table xmlns:py="http://genshi.edgewall.org/">
53<tr py:for="row in table">
54<td py:for="c in row.values()" py:content="c"/>
55</tr>
56</table>
57""")
58
59genshi_tmpl2 = MarkupTemplate("""
60<table xmlns:py="http://genshi.edgewall.org/">$table</table>
61""")
62
63genshi_text_tmpl = NewTextTemplate("""
64<table>
65{% for row in table %}<tr>
66{% for c in row.values() %}<td>$c</td>{% end %}
67</tr>{% end %}
68</table>
69""")
70
71if DjangoTemplate:
72    django_tmpl = DjangoTemplate("""
73    <table>
74    {% for row in table %}
75    <tr>{% for col in row.values %}{{ col|escape }}{% endfor %}</tr>
76    {% endfor %}
77    </table>
78    """)
79
80    def test_django():
81        """Djange template"""
82        context = DjangoContext({'table': table})
83        django_tmpl.render(context)
84
85if MakoTemplate:
86    mako_tmpl = MakoTemplate("""
87<table>
88  % for row in table:
89    <tr>
90      % for col in row.values():
91        <td>${ col | h  }</td>
92      % endfor
93    </tr>
94  % endfor
95</table>
96""")
97    def test_mako():
98        """Mako Template"""
99        mako_tmpl.render(table=table)
100
101def test_genshi():
102    """Genshi template"""
103    stream = genshi_tmpl.generate(table=table)
104    stream.render('html', strip_whitespace=False)
105
106def test_genshi_text():
107    """Genshi text template"""
108    stream = genshi_text_tmpl.generate(table=table)
109    stream.render('text')
110
111def test_genshi_builder():
112    """Genshi template + tag builder"""
113    stream = tag.TABLE([
114        tag.tr([tag.td(c) for c in row.values()])
115        for row in table
116    ]).generate()
117    stream = genshi_tmpl2.generate(table=stream)
118    stream.render('html', strip_whitespace=False)
119
120def test_builder():
121    """Genshi tag builder"""
122    stream = tag.TABLE([
123        tag.tr([
124            tag.td(c) for c in row.values()
125        ])
126        for row in table
127    ]).generate()
128    stream.render('html', strip_whitespace=False)
129
130if kid:
131    kid_tmpl = kid.Template("""
132    <table xmlns:py="http://purl.org/kid/ns#">
133    <tr py:for="row in table">
134    <td py:for="c in row.values()" py:content="c"/>
135    </tr>
136    </table>
137    """)
138
139    kid_tmpl2 = kid.Template("""
140    <html xmlns:py="http://purl.org/kid/ns#">$table</html>
141    """)
142
143    def test_kid():
144        """Kid template"""
145        kid_tmpl.table = table
146        kid_tmpl.serialize(output='html')
147
148    if cet:
149        def test_kid_et():
150            """Kid template + cElementTree"""
151            _table = cet.Element('table')
152            for row in table:
153                td = cet.SubElement(_table, 'tr')
154                for c in row.values():
155                    cet.SubElement(td, 'td').text=str(c)
156            kid_tmpl2.table = _table
157            kid_tmpl2.serialize(output='html')
158
159if et:
160    def test_et():
161        """ElementTree"""
162        _table = et.Element('table')
163        for row in table:
164            tr = et.SubElement(_table, 'tr')
165            for c in row.values():
166                et.SubElement(tr, 'td').text=str(c)
167        et.tostring(_table)
168
169if cet:
170    def test_cet(): 
171        """cElementTree"""
172        _table = cet.Element('table')
173        for row in table:
174            tr = cet.SubElement(_table, 'tr')
175            for c in row.values():
176                cet.SubElement(tr, 'td').text=str(c)
177        cet.tostring(_table)
178
179if neo_cgi:
180    def test_clearsilver():
181        """ClearSilver"""
182        hdf = neo_util.HDF()
183        for i, row in enumerate(table):
184            for j, c in enumerate(row.values()):
185                hdf.setValue("rows.%d.cell.%d" % (i, j), cgi.escape(str(c)))
186
187        cs = neo_cs.CS(hdf)
188        cs.parseStr("""
189<table><?cs
190  each:row=rows
191?><tr><?cs each:c=row.cell
192  ?><td><?cs var:c ?></td><?cs /each
193?></tr><?cs /each?>
194</table>""")
195        cs.render()
196
197
198def run(which=None, number=10):
199    tests = ['test_builder', 'test_genshi', 'test_genshi_text',
200             'test_genshi_builder', 'test_mako', 'test_kid', 'test_kid_et',
201             'test_et', 'test_cet', 'test_clearsilver', 'test_django']
202
203    if which:
204        tests = filter(lambda n: n[5:] in which, tests)
205
206    for test in [t for t in tests if hasattr(sys.modules[__name__], t)]:
207        t = timeit.Timer(setup='from __main__ import %s;' % test,
208                         stmt='%s()' % test)
209        time = t.timeit(number=number) / number
210
211        if time < 0.00001:
212            result = '   (not installed?)'
213        else:
214            result = '%16.2f ms' % (1000 * time)
215        print '%-35s %s' % (getattr(sys.modules[__name__], test).__doc__, result)
216
217
218if __name__ == '__main__':
219    which = [arg for arg in sys.argv[1:] if arg[0] != '-']
220
221    if '-p' in sys.argv:
222        import cProfile, pstats
223        prof = cProfile.Profile()
224        prof.run('run(%r, number=1)' % which)
225        stats = pstats.Stats(prof)
226        stats.strip_dirs()
227        stats.sort_stats('time', 'calls')
228        stats.print_stats(25)
229        if '-v' in sys.argv:
230            stats.print_callees()
231            stats.print_callers()
232    else:
233        run(which)
Note: See TracBrowser for help on using the repository browser.