Performance of the Genshi Template Engine
The directory examples/bench has some very simple benchmarks.
It should be noted that text-based template engines generally have a lot less work to do than XML-based ones, simply because their functionality is limited to processing text as opposed to processing markup.
All tests were run under on Ubuntu 12.10 (Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz) using Genshi 0.7.0.
basic benchmark
The basic.py benchmark is based on a relatively simple template that includes a lot of the common templating constructs, such as includes/inheritance, looping, conditionals, macros, etc.
Template Engine | Python version | Rendering time (less is better) | Notes |
Genshi | CPython 2.7 | 1.06 ms | Genshi markup template |
Genshi_text | CPython 2.7 | 0.36 ms | The text-based template engine included with Genshi |
Genshi | CPython 3.3 | 1.41 ms | Genshi markup template |
Genshi_text | CPython 3.3 | 0.49 ms | The text-based template engine included with Genshi |
Genshi | PyPy 2.7 | 2.42 ms | Genshi markup template |
Genshi_text | PyPy 2.7 | 0.50 ms | The text-based template engine included with Genshi |
The test template is rather simple right now and doesn't make much use of the advanced features provided by either Genshi, because then it would be impossible to implement an equivalent template using other template languages.
bigtable benchmark
The bigtable.py benchmark renders a large HTML table (with 1000 rows and 10 columns) in two nested loops, where each cell contains a variable reference. This basically measures the raw throughput of the template engine, while not using any advanced features.
Template Engine | Python version | Rendering time (less is better) | Notes |
Genshi tag builder | CPython 2.7 | 192 ms | |
Genshi template | CPython 2.7 | 107 ms | |
Genshi text template | CPython 2.7 | 74 ms | |
Genshi template + tag builder | CPython 2.7 | 212 ms | |
Genshi tag builder | CPython 3.3 | 266 ms | |
Genshi template | CPython 3.3 | 134 ms | |
Genshi text template | CPython 3.3 | 95 ms | |
Genshi template + tag builder | CPython 3.3 | 287 ms | |
Genshi tag builder | PyPy 2.7 | 103 ms | |
Genshi template | PyPy 2.7 | 74 ms | |
Genshi text template | PyPy 2.7 | 43 ms | |
Genshi template + tag builder | PyPy 2.7 | 106 ms |
Ideas for improving the performance
See Christopher Lenz's mail to Trac-dev for a more detailed discussion. Ideas for performance improvements:
- Dropping support for dynamic XInclude tags, i.e. Genshi would need to know what gets included at parse time.
- Moving match template processing to the parsing stage (aka static match templates); or alternatively, drop the match template idea altogether and move to the more conventional model of template inheritance where the master predefines slots that can be filled.
- Compiling templates to Python bytecode.
- Providing a fragment caching system.
- Etc.
Many of these represent substantial changes an would effectively result in Genshi2.
Currently Genshi is roughly twice as fast on PyPy as on CPython 2.7.
See Also
If you need only a subset of Genshi, you may want to have a look at the genshi-compiler project, which claims a 40x times speedup, at the price of leaving out py:match, full i18n support and more ... (so basically it's not usable by Trac for instance).