| # basic.py - basic benchmarks adapted from Genshi |
| # Copyright (C) 2006 Edgewall Software |
| # All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in |
| # the documentation and/or other materials provided with the |
| # distribution. |
| # 3. The name of the author may not be used to endorse or promote |
| # products derived from this software without specific prior |
| # written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
| # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
| # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
| # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| from cgi import escape |
| import os |
| from StringIO import StringIO |
| import sys |
| import timeit |
| |
| __all__ = ['mako', 'mako_inheritance', 'cheetah', 'django', 'myghty', 'genshi', 'kid'] |
| |
| 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 myghty(dirname, verbose=False): |
| from myghty import interp |
| interpreter = interp.Interpreter(component_root=dirname) |
| def render(): |
| data = dict(title='Just a test', user='joe', |
| items=['Number %d' % num for num in range(1, 15)]) |
| buffer = StringIO() |
| interpreter.execute("template.myt", request_args=data, out_buffer=buffer) |
| return buffer.getvalue() |
| if verbose: |
| print render() |
| return render |
| |
| def mako(dirname, verbose=False): |
| from mako.template import Template |
| from mako.lookup import TemplateLookup |
| lookup = TemplateLookup(directories=[dirname], filesystem_checks=False, disable_unicode=True) |
| template = lookup.get_template('template.html') |
| def render(): |
| return template.render(title="Just a test", user="joe", list_items=[u'Number %d' % num for num in range(1,15)]) |
| if verbose: |
| print template.code, render() |
| return render |
| mako_inheritance = mako |
| |
| def cheetah(dirname, verbose=False): |
| from Cheetah.Template import Template |
| filename = os.path.join(dirname, 'template.tmpl') |
| template = Template(file=filename) |
| def render(): |
| template.__dict__.update({'title': 'Just a test', 'user': 'joe', |
| 'list_items': [u'Number %d' % num for num in range(1, 15)]}) |
| return template.respond() |
| |
| if verbose: |
| print dir(template) |
| print template.generatedModuleCode() |
| print render() |
| return render |
| |
| def django(dirname, verbose=False): |
| from django.conf import settings |
| settings.configure(TEMPLATE_DIRS=[os.path.join(dirname, 'templates')]) |
| 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): |
| import kid |
| kid.path = kid.TemplatePath([dirname]) |
| template = kid.Template(file='template.kid') |
| def render(): |
| template = kid.Template(file='template.kid', |
| title='Just a test', user='joe', |
| items=['Number %d' % num for num in range(1, 15)]) |
| return template.serialize(output='xhtml') |
| |
| 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(), |
| 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 hotshot, hotshot.stats |
| prof = hotshot.Profile("template.prof") |
| benchtime = prof.runcall(run, engines, number=100, verbose=verbose) |
| stats = hotshot.stats.load("template.prof") |
| stats.strip_dirs() |
| stats.sort_stats('time', 'calls') |
| stats.print_stats() |
| else: |
| run(engines, verbose=verbose) |