= Performance of the Genshi Template Engine = The directory [source:/trunk/examples/bench/ 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 [source:/trunk/examples/bench/basic.py 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 || || [http://kid-templating.org/ 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. || || [http://www.djangoproject.com/documentation/templates/ Django] || 1.38 ms || Text-based template engine that comes with the [http://www.djangoproject.com/ Django] framework. || || [http://www.clearsilver.net/ Clearsilver] || 0.30 ms || !ClearSilver is a text-based template engine written in C. || || [http://www.makotemplates.org/ Mako] || 0.31 ms || Text-based template engine written in Python || || [http://www.owlfish.com/software/simpleTAL/ SimpleTAL] || 2.84 ms || Another XML-based template engine written in Python, based on the [http://www.zope.org/ 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 [source:/trunk/examples/bench/bigtable.py 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 || || [http://kid-templating.org/ Kid] || 1101 ms || || || [http://www.djangoproject.com/documentation/templates/ Django] || 474 ms || || || [http://www.makotemplates.org/ Mako] || 96 ms || || || [http://effbot.org/zone/element-index.htm ElementTree] || 293 ms || ''Not a template engine'': the benchmark simply constructs the XML tree in memory and serializes it. || || [http://effbot.org/zone/celementtree.htm cElementTree] || 179 ms || ''Not a template engine'': the benchmark simply constructs the XML tree in memory and serializes it. || || [http://www.clearsilver.net/ 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: [source:/trunk/examples/basic/ 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 || || || [http://kid-templating.org/ Kid] || 6.93 ms || || == Ideas for improving the performance == In a [http://groups.google.com/group/trac-dev/msg/fe3bfd51a880a3e7 mail on Trac-dev] in April 2010, Christopher Lenz wrote the following, in reply to Eirik Schwenke: {{{ #!div style="margin: 1em 2em; border: 2px solid #ccc" > 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. }}}