A few weeks ago, we announced that we would be upgrading our templating language from Django to Jinja and discussed some of the reasons for doing so. At the time we promised a follow-up with more depth on the technical details. Today we’re here to fulfill that promise.
As mentioned previously, the three big reasons we’re upgrading to Jinja are that it’s highly extensible, fast, and easy to sandbox. We also considered Genshi and Mako, but eventually landed on Jinja because, in addition to fulfilling our criteria, Jinja had the advantage of being based on Django. This meant that it already rendered almost all of our Django templates correctly from the get go and wouldn’t require as much work to migrate everyone over.
Clearly Jinja has a lot to offer, but today we want to focus on the performance advantages, so let’s get benchmarking!
A New Challenger Approaches
To measure performance of Jinja and Django templates we chose three benchmark parameters. The number of variables contained, the number of items being iterated in a for loop, and a real world test using actual email templates.
To keep the tests’ performance measurements fair between Jinja and Django the parsed versions of the templates were not cached. So unless otherwise stated, render can be taken to mean parse then render.
Starting with the variables it is easy to see that Django seems to have a clear advantage. For most real world templates there will be far less than even fifty rendered variables, but still it is interesting how much faster Jinja’s performance decreases as this number increases.
In this same test we see that Jinja uses about six megabytes less memory than Django for normal inputs. Again we see the memory used by Jinja linearly increasing with the number of template variables, where Django’s memory usage is pretty much flat.
When rendering variables in a loop the story is similar: for all practical inputs Django appears to render faster than Jinja. Interestingly though, this time Django slows down in a similar manner to Jinja in the first test.
For memory usage in this test, again Jinja uses quite a bit less memory than Django at all scales in the test range.
The performance of extensions is where Jinja really shines. Our new Jinja snippets render significantly faster, and as expected us much less memory than our Django equivalent.
Real World (w/ Caching) Testing
The next part of the bench mark was to test performance with real data. Five thousand different templates from the Sendwithus database were rendered with real world data. Given how Django out performed Jinja on the benchmarks, we expected that it would perform similarly on real templates. To our surprise over our dataset Jinja was nearly 4.5 times faster than Django.
Given the huge performance differences between the our benchmarks and the performance of rendering real templates within Sendwithus, we are reminded to be wary of somewhat contrived benchmarks. Still, the benchmark performance gains on our Jinja snippets extension is promising. One of the reasons we were most stoked about switching to Jinja is the ability to easily write cool and performant new template extensions.