Benchmark¶
A few simple benchmarks can be found in the Genshi 0.6 release. I’ve written some
TDI code for bench/basic.py
and bench/bigtable.py
. See
the chapters below for the code itself. Here are the results (CPython
2.7.3 on my box):
Name | Basic | Bigtable |
---|---|---|
Kid (+ cElementTree) | 4.29 ms | 759.89 ms |
Genshi Template | 2.05 ms | 205.52 ms |
Django template | 1.53 ms | 461.24 ms |
cElementTree | - | 139.74 ms |
Clearsilver | 0.16 ms | 54.27 ms |
Mako | 0.18 ms | 35.94 ms |
TDI | 0.06 ms | 20.05 ms |
TDI (less readable) | - | 14.69 ms |
Basic code¶
The following code was entered into basic.py:
def tdi(dirname, verbose=False): from tdi import html template = html.from_files(['base.html', 'template.html'], basedir=dirname) class Model(dict): def render_title(self, node): node.content = self['title'] def render_hello1(self, node): node.content = 'hello %s' % self['user'] def render_hello2(self, node): node.content = 'hello me' def render_hello3(self, node): node.content = 'hello world' def render_items(self, node): items = self['items'] if not items: return node.remove() for subnode, item in node.item.iterate(items): subnode.content = item subnode['class'] = 'last' def render(): return template.render_string(Model( title='Just a test', user='joe', items=['Number %d' % num for num in range(1, 15)] )) if verbose: print render() return render
The templates are:
tdi/base.html
:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <title tdi="title"></title> </head> <body> <div id="header"> <h1 tdi="title">...</h1> </div> <tdi tdi:overlay="->content" /> <div id="footer"> </div> </body> </html>
and tdi/template.html
:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <body> <tdi tdi:overlay="<-content"> <p tdi="hello1">hello</p> <p tdi="hello2">hello</p> <p tdi="hello3">hello</p> <h2>Loop</h2> <ul tdi="items"> <li tdi="item">...</li><li tdi=":-item"> </li> </ul> </tdi> </body> </html>
Bigtable code¶
try:
from tdi import html as tdi
except ImportError:
tdi = None
if tdi:
tdi_tmpl = tdi.from_string("""
<table>
<tr tdi="row">
<td tdi="col"></td>
</tr>
</table>
""")
class tdimodel(dict):
def render_row(self, node):
for rownode, row in node.iterate(self['table']):
for colnode, col in rownode.col.iterate(row.itervalues()):
colnode.content = col
def test_tdi(tdimodel=tdimodel):
"""TDI template"""
tdi_tmpl.render_string(tdimodel(table=table))
class tdimodel_fast(dict):
def render_row(self, node):
def row_repeater(node, row):
def col_repeater(node, col):
node.content = col
node.col.repeat(col_repeater, row.itervalues())
return True
node.repeat(row_repeater, self['table'])
def test_tdi_fast(tdimodel=tdimodel_fast):
"""TDI template (faster) """
tdi_tmpl.render_string(tdimodel(table=table))
class tdimodel_cheat(dict):
def render_row(self, node):
for colnode, col in \
node.col.iterate(self['table'][0].itervalues()):
colnode.content = col
node.repeat(None, self['table'])
def test_tdi_cheat(tdimodel=tdimodel_cheat):
"""TDI template (cheated)"""
tdi_tmpl.render_string(tdimodel(table=table))
test_tdi
, test_tdi_fast
and test_tdi_cheat
were added to the
run()
function as well.
The cheating code (test_tdi_cheat
) variant is incredibly fast
(8.33 ms in the benchmark run above) and generates the correct HTML,
but, well, it just generates the columns once and copies the whole row a
thousand times. It effectively loops 1010 times instead of the 10000
times. I made it just for fun and because it’s possible, of course ;-)
The test_tdi
and test_tdi_fast
variants however do the right thing.