mirror of
https://github.com/edgewall/genshi.git
synced 2026-02-06 00:47:39 +01:00
219 lines
7.0 KiB
Python
219 lines
7.0 KiB
Python
# -*- encoding: utf-8 -*-
|
|
# Template language benchmarks
|
|
#
|
|
# Objective: Test general templating features using a small template
|
|
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
import sys
|
|
import timeit
|
|
|
|
try:
|
|
from html import escape
|
|
except ImportError:
|
|
from cgi import escape
|
|
|
|
try:
|
|
from io import StringIO
|
|
except ImportError:
|
|
from StringIO import StringIO
|
|
|
|
__all__ = ['clearsilver', 'mako', 'django', 'kid', 'genshi', 'genshi_text',
|
|
'simpletal']
|
|
|
|
def genshi(dirname, verbose=False):
|
|
from genshi.template import TemplateLoader
|
|
loader = TemplateLoader([dirname], auto_reload=False)
|
|
template = loader.load('template.html')
|
|
def render():
|
|
data = dict(title='Just a test', user='joe',
|
|
items=['Number %d' % num for num in range(1, 15)])
|
|
return template.generate(**data).render('xhtml')
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def genshi_text(dirname, verbose=False):
|
|
from genshi.core import escape
|
|
from genshi.template import TemplateLoader, NewTextTemplate
|
|
loader = TemplateLoader([dirname], auto_reload=False)
|
|
template = loader.load('template.txt', cls=NewTextTemplate)
|
|
def render():
|
|
data = dict(escape=escape, title='Just a test', user='joe',
|
|
items=['Number %d' % num for num in range(1, 15)])
|
|
return template.generate(**data).render('text')
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def mako(dirname, verbose=False):
|
|
try:
|
|
from mako.lookup import TemplateLookup
|
|
except ImportError:
|
|
print('Mako not installed, skipping', file=sys.stderr)
|
|
return lambda: None
|
|
lookup = TemplateLookup(directories=[dirname], filesystem_checks=False)
|
|
template = lookup.get_template('template.html')
|
|
def render():
|
|
data = dict(title='Just a test', user='joe',
|
|
list_items=['Number %d' % num for num in range(1, 15)])
|
|
return template.render(**data)
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def cheetah(dirname, verbose=False):
|
|
# FIXME: infinite recursion somewhere... WTF?
|
|
try:
|
|
from Cheetah.Template import Template
|
|
except ImportError:
|
|
print('Cheetah not installed, skipping', file=sys.stderr)
|
|
return lambda: None
|
|
class MyTemplate(Template):
|
|
def serverSidePath(self, path): return os.path.join(dirname, path)
|
|
filename = os.path.join(dirname, 'template.tmpl')
|
|
template = MyTemplate(file=filename)
|
|
|
|
def render():
|
|
template = MyTemplate(file=filename,
|
|
searchList=[{'title': 'Just a test', 'user': 'joe',
|
|
'items': [u'Number %d' % num for num in range(1, 15)]}])
|
|
return template.respond()
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def clearsilver(dirname, verbose=False):
|
|
try:
|
|
import neo_cgi
|
|
except ImportError:
|
|
print('ClearSilver not installed, skipping', file=sys.stderr)
|
|
return lambda: None
|
|
neo_cgi.update()
|
|
import neo_util
|
|
import neo_cs
|
|
def render():
|
|
hdf = neo_util.HDF()
|
|
hdf.setValue('hdf.loadpaths.0', dirname)
|
|
hdf.setValue('title', escape('Just a test'))
|
|
hdf.setValue('user', escape('joe'))
|
|
for num in range(1, 15):
|
|
hdf.setValue('items.%d' % (num - 1), escape('Number %d' % num))
|
|
cs = neo_cs.CS(hdf)
|
|
cs.parseFile('template.cs')
|
|
return cs.render()
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def django(dirname, verbose=False):
|
|
try:
|
|
from django.conf import settings
|
|
settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')])
|
|
except ImportError:
|
|
print('Django not installed, skipping', file=sys.stderr)
|
|
return lambda: None
|
|
from django import template, templatetags
|
|
from django.template import loader
|
|
templatetags.__path__.append(os.path.join(dirname, 'templatetags'))
|
|
tmpl = loader.get_template('template.html')
|
|
|
|
def render():
|
|
data = {'title': 'Just a test', 'user': 'joe',
|
|
'items': ['Number %d' % num for num in range(1, 15)]}
|
|
return tmpl.render(template.Context(data))
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def kid(dirname, verbose=False):
|
|
try:
|
|
import kid
|
|
except ImportError:
|
|
print("Kid not installed, skipping", file=sys.stderr)
|
|
return lambda: None
|
|
kid.path = kid.TemplatePath([dirname])
|
|
template = kid.load_template('template.kid').Template
|
|
def render():
|
|
return template(
|
|
title='Just a test', user='joe',
|
|
items=['Number %d' % num for num in range(1, 15)]
|
|
).serialize(output='xhtml')
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def simpletal(dirname, verbose=False):
|
|
try:
|
|
from simpletal import simpleTAL, simpleTALES
|
|
except ImportError:
|
|
print("SimpleTAL not installed, skipping", file=sys.stderr)
|
|
return lambda: None
|
|
fileobj = open(os.path.join(dirname, 'base.html'))
|
|
base = simpleTAL.compileHTMLTemplate(fileobj)
|
|
fileobj.close()
|
|
fileobj = open(os.path.join(dirname, 'template.html'))
|
|
template = simpleTAL.compileHTMLTemplate(fileobj)
|
|
fileobj.close()
|
|
def render():
|
|
ctxt = simpleTALES.Context(allowPythonPath=1)
|
|
ctxt.addGlobal('base', base)
|
|
ctxt.addGlobal('title', 'Just a test')
|
|
ctxt.addGlobal('user', 'joe')
|
|
ctxt.addGlobal('items', ['Number %d' % num for num in range(1, 15)])
|
|
buf = StringIO()
|
|
template.expand(ctxt, buf)
|
|
return buf.getvalue()
|
|
|
|
if verbose:
|
|
print(render())
|
|
return render
|
|
|
|
def run(engines, number=2000, verbose=False):
|
|
basepath = os.path.abspath(os.path.dirname(__file__))
|
|
for engine in engines:
|
|
dirname = os.path.join(basepath, engine)
|
|
if verbose:
|
|
print('%s:' % engine.capitalize())
|
|
print('--------------------------------------------------------')
|
|
else:
|
|
print('%s:' % engine.capitalize(), end=' ')
|
|
t = timeit.Timer(setup='from __main__ import %s; render = %s(r"%s", %s)'
|
|
% (engine, engine, dirname, verbose),
|
|
stmt='render()')
|
|
time = t.timeit(number=number) / number
|
|
if verbose:
|
|
print('--------------------------------------------------------')
|
|
print('%.2f ms' % (1000 * time))
|
|
if verbose:
|
|
print('--------------------------------------------------------')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
engines = [arg for arg in sys.argv[1:] if arg[0] != '-']
|
|
if not engines:
|
|
engines = __all__
|
|
|
|
verbose = '-v' in sys.argv
|
|
|
|
if '-p' in sys.argv:
|
|
import cProfile, pstats
|
|
prof = cProfile.Profile()
|
|
prof.run('run(%r, number=200, verbose=%r)' % (engines, verbose))
|
|
stats = pstats.Stats(prof)
|
|
stats.strip_dirs()
|
|
stats.sort_stats('calls')
|
|
stats.print_stats(25)
|
|
if verbose:
|
|
stats.print_callees()
|
|
stats.print_callers()
|
|
else:
|
|
run(engines, verbose=verbose)
|