为啥 django 模板渲染字典这么慢?

Posted

技术标签:

【中文标题】为啥 django 模板渲染字典这么慢?【英文标题】:Why do django templates render dictionaries so slowly?为什么 django 模板渲染字典这么慢? 【发布时间】:2012-10-22 05:42:25 【问题描述】:

当我使用 django 1.4 的默认模板系统渲染一个中等复杂的字典(4 级深度,~2K 数据点)时,模板渲染步骤需要超过 2800 毫秒。当我直接从 python 执行 html-gen 时,它需要大约 80 毫秒。即使使用另一个模板库 (jinja2) 也可以在 300 毫秒内呈现相同的数据(实际上,几乎完全相同的模板语法 - 因为 jinja2 几乎是一个替代品)。

有趣的是,在 django 的模板系统中,您甚至不必真正渲染模板中的字典来导致这个性能问题......您所要做的就是 pass em> 它作为模板的可用变量。我的一个朋友建议这可能意味着系统是,“......做一个防御性的副本或(更愚蠢的)一个理解 [which] 由于运行构造函数而需要时间”

有人知道为什么 django 的默认模板系统需要这么长时间来渲染字典吗?

* 我将在下面添加请求的详细信息 *

我在调试模式下运行,并将 DebugToolbarMiddleware 设置为我的中间件类之一。我的 settings.py 文件包括:

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

和....

# rendering like this
return render(
    request,
    template_name='ltm/search_results.html',
    context_instance=RequestContext(request, 
        'menus': menus,
        'results': result_dict
    )
)

【问题讨论】:

你为什么不 cProfile 运行服务器而不是我们猜测?我们没有你的数据。你有什么花哨的上下文处理器吗? 您能提供一个带有虚拟数据的可运行示例吗? 不回答您的问题,但值得一看:Jinja2 adapter for Django。 @PavelAnossov... +1 简短回答?因为这是我第一次听说 cProfile :) 我会继续努力并发布更新。可能需要一些时间,因为我在截止日期前工作,并且能够使用 jinja2 回避这个问题并继续处理其他问题。只是好奇这是否是更有经验的人的已知问题。但你说得很好,这很可能是我的设置所特有的。 Jinja2 的性能比 Django 模板好很多。 【参考方案1】:

如果您能向我们提供您的模板代码以更好地了解我们正在处理的模板处理类型,那就太好了。

首先,您遍历字典内容的方式之间存在潜在差异。 dict.items() 返回一个元组列表,它会消耗额外的内存并需要时间来初始构造,但如果您使用 dict.iteritems(),访问键和值比通过生成器更快。

当您传入以点 . 开头的变量名时,还会涉及一些开销,例如foo.bar.baz,这里 Django 的模板执行所谓的variable lookup,试图确定您是通过键、对象的属性还是通过索引访问列表项。我没有用过 Jinja2,所以变量查找的问题可能完全不相关,但如果两者之间存在差异,则值得考虑。

在任何一种情况下,由于您处理的是一个相当大的字典,因此如果您可以在视图中重新组织它的结构以简化稍后在模板中访问数据的方式,这可能会有所帮助。

【讨论】:

感谢您发布此信息。我没有时间更新我的问题,这让我很生气。当我这样做时,我计划尝试使用一个非常简单的示例来重现该行为。在我的测试中,我尝试了 items() 和 iteritems()。我非常担心我在模板中引用字典的方式会导致问题。这就是我测试用“hello world”模板替换的原因。重要的是要了解这对渲染时间几乎没有影响。出于这个原因,我很确定缓慢与实际渲染无关。

以上是关于为啥 django 模板渲染字典这么慢?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 Jinja2 模板的渲染速度不比 Django 快?

Django 模板渲染

在Django模板中渲染有序反转字典值

Django 渲染 dict 性能

AJAX成功的Django渲染模板

django 第四天模板渲染