Edgewall Software

Version 40 (modified by cboos, 10 years ago) (diff)

oops, still 0.11 here ;-)

Performance of the Genshi Template Engine

The directory examples/bench has some very simple benchmarks to compare the performance of Genshi to other template engines.

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.

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.

All tests run under Python 2.4.4 on Mac OS X (iMac 2.16 GHz).

Template Engine Rendering time (less is better) Notes
Genshi 2.65 ms Genshi markup template
Genshi (Text) 0.98 ms The text-based template engine included with Genshi
Kid 6.16 ms Kid templates are compiled to Python byte-code. The cElementTree implementation was used for this test, although using the Python implementation doesn't appear to make a significant difference.
Django 1.38 ms Text-based template engine that comes with the Django framework.
Clearsilver 0.30 ms ClearSilver is a text-based template engine written in C.
Mako 0.31 ms Text-based template engine written in Python
SimpleTAL 2.84 ms Another XML-based template engine written in Python, based on the Zope template engine (TAL).

The test template is rather simple right now and doesn't make much use of the advanced features provided by either Genshi or Kid, 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 Rendering time (less is better) Notes
Genshi 390 ms Genshi markup template
Genshi (Text) 197 ms The text-based template engine included with Genshi
Kid 1101 ms
Django 474 ms
Mako 96 ms
ElementTree 293 ms Not a template engine: the benchmark simply constructs the XML tree in memory and serializes it.
cElementTree 179 ms Not a template engine: the benchmark simply constructs the XML tree in memory and serializes it.
Clearsilver 83 ms

Note that both ET and cET are using Python code for serialization.

Another benchmark

There's another simple benchmark in the Genshi repository: examples/basic. That example is however only implemented for Genshi and Kid, as it makes use of features not found in other template languages. Here are the numbers:

Template Engine Rendering time (less is better) Notes
Genshi 2.89 ms
Kid 6.93 ms

Ideas for improving the performance

In a mail on Trac-dev in April 2010, Christopher Lenz wrote the following, in reply to Eirik Schwenke:

Anyway, I think there are three seperate issues, that all warrant discussion:

a) Is the speed of genshi doomed due to genshis design? And if so,

should we for *speed reasons* give up on genshi ?

The current design is inefficient in a number of ways. The whole design choice that everything is streamed through the pipeline event by event (SAX-style) using Python generators has proved to be rather poor. That match templates are processed at render time makes their use quite expensive, and it certainly doesn't scale to a larger number of match templates.

It would be possible to move Genshi towards a more efficient implementation by:

  • 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.

It would still not be in the same league as highly optimized text template engine such as Mako or Jinja2, but I think it would be totally usable. As a point of reference, Genshi trunk is in some cases actually faster than Django templates in raw throughput when you don't use things like match templates (last time I tested at least), and lots of sites use Django templates. I think that doing the above changes would make Genshi consistently faster than Django templates (at least the current implementation).

But those changes also require a lot of work, and would obviously take away some features people (including Trac and Trac plugins) may have been relying on. It'd basically be Genshi2 ;)

c) Does genshi's stream-filters provide enough of an advandage

to push for b) over a) ?

Not sure. Stream filtering is used for a couple things, most importantly form filling and localization. Removing stream filtering leaves two alternative ways to achieve these (and similar) tasks:

  • post-process the generated output (parse/transform)
  • take care of everything right in the template, i.e. manually fill in form values, gettext() all strings, etc.

Stream filters are nice in that they let you implement "cross-cutting concerns" outside of the templates, and doesn't require a post-processing stage. Whether that's worth the cost I don't know.

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).