When we first announced that we would be upgrading our templating language from Django to Jinja, we discussed some of our reasons for doing so. This follow-up provides more depth on the technical details.
We upgraded to Jinja because 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 from the get-go, it rendered almost all of our Django templates correctly and would require less work to migrate everyone over.
Let’s take a look at some of our performance benchmarks.
A New Challenger Approaches
To measure the 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 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.
When just looking at variables vs render time, it’s easy to see that Django seems to have a clear advantage. For most real-world templates, there will be far fewer than fifty rendered variables, but it’s still interesting to see how much faster Jinja’s performance decreases as this number increases.
In this test, we see that Jinja uses about six megabytes less memory than Django for normal inputs. Again, we see the memory used by Jinja increasing linearly with the number of template variables, where Django’s memory usage remains pretty much flat.
The story is similar when rendering variables in a loop: for all practical inputs, Django appears to render faster than Jinja. Interestingly though, this time Django slows down in much the same way Jinja did in the first test, the number of variables vs render time.
When testing the number of loop iterations vs memory usage, again Jinja used significantly less memory than Django, throughout the test range.
The performance of extensions is where Jinja really shines. Our new Jinja snippets rendered significantly faster and, as expected, used much less memory than our Django equivalents.
Real World (w/ Caching) Testing
The next step was to test performance with real data. Five thousand different templates from the Sendwithus database were rendered with real-world data. Given the way Django outperformed Jinja in the benchmarks, we expected similar performance on real templates. But to our surprise, Jinja was nearly 4.5 times faster than Django across the dataset.
By caching the compiled Jinja templates, we were able to improve performance by more than 10x over our old email rendering system.
Conclusions
Given the huge performance differences between our benchmarks and the performance of rendering real templates within Sendwithus, we were 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 was the ability to easily write innovative and high-performing new template extensions.