Thursday, July 19, 2012

Python Fastest Template Engine

What is the fastest template system for Python? Django, Kid, Genshi are quite slow in compare to those used in this post. See also:
  • Comprehensive benchmarks for various template include, extends and widget directives are here.
The benchmark is based on wheezy.template big table test for rendering a 10x1000 HTML table in unicode. Latest available versions (September 24, 2014):
  1. bottle 0.12.7
  2. chameleon 2.16
  3. cheetah 2.4.4
  4. django 1.7
  5. jinja2 2.7.3
  6. mako 1.0.0
  7. durusworks qpy 1.2
  8. spitfire 0.7.15
  9. tenjin 1.1.1
  10. tornado 4.0.2
  11. web2py 2.0.9
  12. wheezy.template 0.1.155
Let setup virtualenv environment:
virtualenv env
env/bin/easy_install -O2 bottle chameleon cheetah django \
  jinja2 mako tenjin webext tornado wheezy.html \
  wheezy.template
Download bigtable.py test:
wget https://bitbucket.org/akorn/wheezy.template/raw/tip/demos/bigtable/bigtable.py
And run it:
env/bin/python bigtable.py
Raw numbers (Intel Core 2 Duo @ 2.4 GHz x 2; OS X 10.9):
cpython 2.7
                     msec    rps  tcalls  funcs
bottle              93.66  10.68  163016     23
chameleon           71.22  14.04  161031     24
cheetah            183.67   5.44  225019     22
django            1081.69   0.92 1504070     59
jinja2              58.22  17.18   60018     26
list_append         11.47  87.19   63007      9
list_extend         10.02  99.82   23007      9
mako                46.87  21.34   93035     36
qpy_list_append    282.92   3.53  505023     14
spitfire            43.33  23.08  124016     23
tenjin              13.43  74.47   43010     13
tornado             80.38  12.44  233021     23
web2py             106.45   9.39  295015     20
wheezy_template     11.95  83.66   63009     11


pypy 2.4
                     msec    rps  tcalls  funcs
bottle              30.85  32.42  163020     25
chameleon           38.15  26.21  193036     25
cheetah            251.87   3.97  755039     33
django              95.55  10.47 1497073     58
jinja2              33.45  29.90  123018     27
list_append         22.09  45.27  103007     10
list_extend         25.27  39.57   63007     10
mako                22.90  43.67  153037     39
qpy_list_append            not installed
spitfire            65.87  15.18  123015     21
tenjin             218.56   4.58   13010     11
tornado             37.50  26.67  233021     23
web2py              30.16  33.15  295015     20
wheezy_template     26.21  38.15  103009     12


cpython 3.3
                     msec    rps  tcalls  funcs
bottle              59.95  16.68  133017     21
chameleon           73.09  13.68  182033     25
cheetah                    not installed
django            1129.29   0.89 1454071     55
jinja2              61.57  16.24   60020     27
list_append         15.34  65.19   63008     10
list_extend         13.90  71.94   23008     10
mako                52.48  19.06   93036     37
qpy_list_append    257.25   3.89  495025     16
spitfire                   not installed
tenjin              50.11  19.96  123012     16
tornado            187.70   5.33  353023     23
web2py                     not installed
wheezy_template     15.26  65.53   63010     12
tcalls - a total number of calls, funcs - a number of unique functions used.

Looking for other benchmarks? Take a look at python web frameworks benchmarks for routing, url reverse and web frameworks.

19 comments:

  1. Great.

    How about str() or html escape?
    I had found that the bottle neck of template engine is in str() or html escape, not in list.append or ''.join().
    (See http://www.slideshare.net/kwatch/how-to-create-a-highspeed-template-engine-in-python for details.)

    If you have time, could you try webext?
    http://www.kuwata-lab.com/tenjin/pytenjin-users-guide.html#tips-webext
    Or enforce tenjin.Engine not to call str() function?

    engine = tenjin.Engine(tostrfunc='')

    # I'm the author of Tenjin and above presentation slide.

    By the way, Jinja2, Mako, Tenjin, and wheezy.template have enough performance for web application. I believe that the performance bottle-neck of web application is not in them.
    But... it is fun to pursue high performance of template engine!

    ReplyDelete
    Replies
    1. Thank you for your comments. I have added webext optimization for tenjin. Please notice, there is huge performance degradation once I have webext installed for pypy (the benchmark for pypy does not have it installed).

      Delete
    2. Note, webext can not be installed into python3.3 virtual environment. Here are few errors:

      webext.c:89:18: error: ‘PyString_Type’ undeclared (first use in this function)
      webext.c:97:23: error: ‘PyInt_Type’ undeclared (first use in this function)

      Delete
  2. It would be interesting to see Cheetah on this list: http://cheetahtemplate.org/

    ReplyDelete
  3. For some reason when I run your bigtable.py benchmark to compare the lot against QPY (https://www.mems-exchange.org/software/), wheezy_template is performing roughly on par with list_append/list_extend. Any ideas why? This on a Linux Mint Debian Edition VM, Python 3.3.2.

    QPY btw is turning in 60 rps vs 29 rps for list_*. I'll put examples up on my site shortly.

    ReplyDelete
    Replies
    1. The wheezy.template translates markup to the code identical to list_append example.

      The difference in results is related to CPU switching for given process, thus you need stick it with one processor (use taskset) and make higher number of iterations (eliminate django first).

      Delete
  4. I've put up a post with some code samples and the results obtained for all the packages I'd installed in a Python 3.3.2 virtual instance:

    http://mikewatkins.ca/2013/06/12/python-fastest-template-engine/

    QPY is fast but isn't a traditional HTML or text templating system as most know them these days. Thankfully when a different itch needs scratching there's a nice selection of web tools for Python developers that are "fast enough".

    ReplyDelete
    Replies
    1. The top of the post has a reference to in-depth benchmarks for template engine directives like include, extends and widgets.

      Delete
    2. The python unicode string concatenation via join is inefficient due to continuous buffer re-locations. While wheezy.template remains pure python implementation it rely on python core efficiency.

      While evaluating impact of such improvement to real world application the result was so minimal that I decided to keep thing as is.

      Good to know QPY went even further by utilizing C optimizations.

      Delete
  5. Another template system that'd be good to have up there is Spitfire.
    https://code.google.com/p/spitfire/

    ReplyDelete
    Replies
    1. I have updated bigtable source code to include Spitfire.

      Delete
  6. Is wheezy.template compatible with Google App Engine?

    ReplyDelete
    Replies
    1. I'd like to know this as well. Although since Google App Engine works with any WSGI compatible frameworks it should work.

      Delete
  7. Hi, maybe i'll have more success here. I can't figure out how to use a variable as a key in whezzy:

    http://stackoverflow.com/questions/21760517/wheezy-template-dictionary-variable-lookup

    ReplyDelete
  8. hi, can you take a look at new bottle template: simpletemplate

    ReplyDelete