Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do django templates render dictionaries so slowly?

When I render a moderately complex dictionary (4 levels deep, ~2K data points) using django 1.4's default template system the template rendering step takes over 2800ms. When I do html-gen directly from python instead it takes ~80ms. Even using another template library (jinja2) renders the same data (in fact, almost exactly the same template syntax - as jinja2 is nearly a drop-in replacement) in under 300ms.

Interestingly, you don't even have to actually render the dictionary in the template to cause this performance issue in django's template system... all you have to do is pass it as an available variable to a template. A friend of mine suggested this may mean the system is, "...doing a defensive copy or (more stupidly) a comprehension [which] will take time due to running constructors"

Anyone know why django's default template system takes so long to render dictionaries?

* I'll work on adding requested details below *

I am running in debug mode and have the DebugToolbarMiddleware set as one of my middleware classes. My settings.py file includes:

TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.request',
)

and....

# rendering like this
return render(
    request,
    template_name='ltm/search_results.html',
    context_instance=RequestContext(request, {
        'menus': menus,
        'results': result_dict
    })
)
like image 849
codemonkey Avatar asked Nov 01 '12 15:11

codemonkey


People also ask

Is Django template slow?

Django templates are slow compared to Jinja2 templates. This may be to do with Jinja2 compiling the templates or perhaps due to the excessive number of function calls Django makes while rendering templates.

Is Jinja slow?

The most significant implication is Jinja being extremely slow when parsing templates with segments of whitespace in tens of thousands.

What is template rendering in Django?

Rendering means interpolating the template with context data and returning the resulting string. The Django template language is Django's own template system. Until Django 1.8 it was the only built-in option available. It's a good template library even though it's fairly opinionated and sports a few idiosyncrasies.


1 Answers

It would be great if you could provide us with your template code to better understand what kind of template processing we're dealing with exactly.

Firstly, there are potential differences between how your traversing the contents of the dictionary. dict.items() returns a list of tuples which consumes additional memory and takes time to initially construct, but it's faster to access keys and values than through a generator if you used dict.iteritems().

There's also some overhead involved when you pass in variable names preceded by a dot ., e.g. foo.bar.baz, where Django's template performs what's called a variable lookup, trying to determine whether your accessing a dictionary item by key, an object's attribute or a list item by index. I haven't used Jinja2, so the issue with variable lookups might be completely unrelated, but it is something worth considering if there's a difference between the two.

In either case, since your dealing with a fairly large dictionary, it might help if you could reorganize it's structure in the view to simplify how the data is accessed later in the template.

like image 137
Filip Dupanović Avatar answered Oct 06 '22 16:10

Filip Dupanović