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. The benchmark is based on wheezy.template big table test for rendering a 10x1000 HTML table in unicode. Latest available versions as of this writing:
  1. chameleon 2.9.2
  2. cheetah 2.4.4
  3. django 1.4.1
  4. jinja2 2.6
  5. mako 0.7.2
  6. tenjin 1.1.1
  7. tornado 2.4
  8. web2py 2.0.9
  9. wheezy.template 0.1.125
Let setup virtualenv environment:
virtualenv env
env/bin/easy_install -O2 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 Quad CPU Q6600 @ 2.40GHz × 4; Kernel Linux 3.2.0-2-686-pae; Debian Testing):
cpython 2.7
                    msec    rps  tcalls  funcs
chameleon          58.03  17.23  151031     23
cheetah           144.97   6.90  225019     22
django            818.14   1.22 1593065     53
jinja2             40.80  24.51   57017     25
list_append        11.10  90.09   63007      9
list_extend        10.14  98.61   23007      9
mako               36.40  27.48   93035     36
tenjin             13.13  76.19   43010     13
tornado            60.72  16.47  233019     22
web2py            106.45   9.39  295015     20
wheezy_template    11.42  87.58   63009     11

pypy 1.9
                    msec    rps  tcalls  funcs
chameleon          28.45  35.15  193036     24
cheetah           194.81   5.13  755039     33   
django            101.67   9.84 1585066     51
jinja2             32.87  30.42  120017     26
list_append        17.73  56.40  103007     10
list_extend        23.64  42.30   63007     10
mako               33.47  29.88  153037     39
tenjin             28.71  34.83  123010     15
tornado            23.38  42.77  233019     22
web2py             30.16  33.15  295015     20
wheezy_template    18.67  53.57  103009     12

cpython 3.3
                    msec    rps  tcalls  funcs
chameleon          63.38  15.78  151032     24
cheetah                   not installed
django                    not installed
jinja2             51.76  19.32   57021     26
list_append        11.04  90.61   63008     10
list_extend        10.07  99.32   23008     10
mako               45.49  21.98   93036     37
tenjin             42.29  23.64  123012     16
tornado           146.75   6.81  353021     22
web2py                    not installed
wheezy_template    11.17  89.50   63010     12
tcalls - a total number of calls, funcs - a number of unique functions used.

Real World Example

There is real world example available in wheezy.web package. It can be found in demo.template application, live demo here. The application has few screens: home, sign up, sign in, etc. The content implementation is available for jinja2, mako, tenjin, wheezy.template and wheezy.template (with preprocessor).
The throughtput was captured using apache benchmark (concurrecy level 500, number of request 1M):
                    /        /en/signin    /en/signup
jinja2              10025    6856          6570
mako                10284    6945          6787
tenjin              12108    7726          7636
wheezy.template     16323    9626          9688
wheezy.template     24017    11711         11606
(preprocessor)
Hardware and software environment specification:
  • Client: Intel Core 2 Quad CPU Q6600 @ 2.40GHz × 4, Kernel 3.2.0-3-686-pae
  • Server: Intel Xeon CPU X3430 @ 2.40GHz x 4, Kernel 3.2.0-3-amd64, uwsgi 1.2.4
  • Debian Testing, Python 2.7.3, LAN 1 Gb
The wheezy.template outperforms jinja2 / mako templates twice while offering the power in: template inheritance, include and import directives plus context preprocessor. Take a look at real world example available in this demo (source). Looking for other benchmarks? Take a look at python benchmarks for routing, url reverse and web frameworks.

6 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