[英]How to profile a Jinja2 template?
我正在分析的Flask应用程序花费很长时间来渲染其Jinja2模板。
我已经安装了flask lineprofilerpanel这很有意思,但遗憾的是我不会深入到模板渲染中查看所有时间花在哪里。
分析Jinja2模板的最佳方法是什么?
好问题。 我通常不太习惯使用剖析器,所以这是学习的好借口。 按照这里的例子: https : //docs.python.org/2/library/profile.html#module-cProfile我编写了一个简单的分析jinja模板的例子。
import cProfile as profile
import pstats
import StringIO
import jinja2
import time
pr = profile.Profile()
def slow():
time.sleep(2)
return "Booga!"
template = jinja2.Template(r'''
{% for i in RANGE1 %}<h1>hello world {{ i}}</h1>{% endfor %}
{% for i in RANGE2 %}<h1>foo bar {{ i}}</h1>{% endfor %}
{{ SLOW() }}
'''
)
# here is the bit we want to profile
pr.enable()
context = {"RANGE1": range(1000000), "RANGE2":range(100), "SLOW":slow}
template.render(context)
pr.disable()
s = StringIO.StringIO()
ps = pstats.Stats(pr, stream=s).sort_stats("cumulative")
ps.print_stats()
print(s.getvalue())
以下是报告的片段:
1000130 function calls in 2.448 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.438 2.438 /usr/local/lib/python2.7/dist-packages/jinja2/environment.py:974(render)
1 0.122 0.122 2.438 2.438 {method 'join' of 'unicode' objects}
1000104 0.315 0.000 2.317 0.000 <template>:5(root)
1 0.000 0.000 2.002 2.002 /usr/local/lib/python2.7/dist-packages/jinja2/runtime.py:169(call)
1 0.000 0.000 2.002 2.002 profilej.py:10(slow)
1 2.002 2.002 2.002 2.002 {time.sleep}
2 0.010 0.005 0.010 0.005 {range}
1 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/environment.py:1015(new_context)
1 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/runtime.py:55(new_context)
1 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/runtime.py:115(__init__)
3 0.000 0.000 0.000 0.000 {hasattr}
1 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/_compat.py:59(<lambda>)
1 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/nodes.py:81(__init__)
3 0.000 0.000 0.000 0.000 {getattr}
3 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/runtime.py:149(resolve)
1 0.000 0.000 0.000 0.000 /usr/local/lib/python2.7/dist-packages/jinja2/runtime.py:126(<genexpr>)
1 0.000 0.000 0.000 0.000 {callable}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1 0.000 0.000 0.000 0.000 {method 'iteritems' of 'dict' objects}
1 0.000 0.000 0.000 0.000 {isinstance}
正如我所说,我没有太多经验来解释分析器的输出,但我认为在这个例子中你可以看到程序在time.sleep上花了2秒多的时间,正如预期的那样,由slow()调用。 剩下的时间由加入占用。 我认为这就是Jinja2如何处理我的两个for循环。
将此示例调整为烧瓶应用程序应该不会太难,只需在模板生成步骤周围添加分析位并将报告写入文件。 也许您甚至可以从Web应用程序中提取模板并将其分析到烧瓶外。
我希望这是有帮助的。
对于像运行Flask服务器这样的多线程应用程序,我发现通常的Python分析工具并不是那么好。
我使用专为多线程应用程序设计的yappi取得了不错的成绩。 这非常简单:
import yappi
yappi.start()
[.. do stuff ..]
yappi.stop()
yappi.convert2pstats(yappi.get_func_stats()).dump_stats('myfile.pstats')
这将配置文件数据保存在pstats
兼容文件中,因此您可以在python中以交互方式检查它:
>>> import pstats
>>> s = pstats.Stats('myfile.pstats')
>>> s.strip_dirs().sort_stats('cumtime').print_stats()
如果你想聪明一点,你可以在Flask处理程序中放置start()
位和stop()
位,这样你就可以点击一个URL来开始分析,驱动你的应用程序,然后点击另一个URL来停止分析并写出统计数据文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.