2014-11-07 19 views
15

Ứng dụng Flask mà tôi đang sử dụng sẽ mất nhiều thời gian để hiển thị các mẫu Jinja2 của nó.Làm cách nào để cấu hình mẫu Jinja2?

Tôi đã cài đặt flask lineprofilerpanel điều thú vị nhưng tiếc là không cho phép tôi đi sâu vào việc hiển thị mẫu để xem tất cả thời gian được sử dụng ở đâu.

Cách tốt nhất để cấu hình mẫu Jinja2 là gì?

+1

@akai: Tôi không biết bình nhưng nó trông giống như python. [* Điều này sẽ làm việc. *] (Http://stackoverflow.com/a/4299378/23771) –

+1

Tôi nghĩ rằng trong profiler trong bình-debugtoolbar bạn có thể thấy tất cả các phương thức được viện dẫn. Nếu bạn lọc thủ công những người có jinja2 ở phía trước (tức là ), bạn có thể ước tính thời gian hiển thị. –

+0

có thể là câu hỏi liên quan? http://stackoverflow.com/questions/618827/optimizing-jinja2-environment-creation – intrepidhero

Trả lời

2

Câu hỏi hay. Tôi thường không có nhiều sử dụng cho một profiler vì vậy đây là một lý do tốt để tìm hiểu. Theo ví dụ ở đây: https://docs.python.org/2/library/profile.html#module-cProfile Tôi đã mã hóa một ví dụ đơn giản về lược tả mẫu 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()) 

Dưới đây là một đoạn của báo cáo:

  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} 

Như tôi đã nói tôi không có nhiều kinh nghiệm giải thích đầu ra của profilers nhưng tôi nghĩ rằng trong ví dụ này bạn sẽ nhìn thấy chương trình dành ít hơn 2 giây trên time.sleep như mong đợi, được gọi bởi slow(). Phần còn lại của thời gian được thực hiện bằng cách tham gia. Tôi cho rằng đó là cách mà Jinja2 xử lý hai vòng của tôi.

Việc áp dụng ví dụ này vào một ứng dụng bình không quá khó, chỉ cần thêm bit lược tả xung quanh bước tạo mẫu và viết báo cáo vào một tệp. Có lẽ bạn thậm chí có thể trích xuất các mẫu của bạn từ ứng dụng web và cấu hình chúng bên ngoài bình.

Tôi hy vọng điều này hữu ích.

+0

Vâng, tôi nghĩ rằng điều này giống như những gì bình-debugtoolbar cho. – akai

1

Đối với ứng dụng đa luồng như máy chủ Flask đang chạy, tôi thấy rằng các công cụ định dạng Python thông thường không phải là tuyệt vời.

Tôi đã có kết quả tốt với yappi được thiết kế cho các ứng dụng đa luồng. Nó khá đơn giản:

import yappi 
yappi.start() 

    [.. do stuff ..] 

yappi.stop() 
yappi.convert2pstats(yappi.get_func_stats()).dump_stats('myfile.pstats') 

Điều đó tiết kiệm dữ liệu hồ sơ trong một tập tin tương thích pstats để bạn có thể kiểm tra nó một cách tương tác trong python:

>>> import pstats 
>>> s = pstats.Stats('myfile.pstats') 
>>> s.strip_dirs().sort_stats('cumtime').print_stats() 

Nếu bạn muốn được thông minh bạn có thể đặt start() bit và các stop() bit trong trình xử lý Flask để bạn có thể nhấn URL để bắt đầu lược tả, thúc đẩy ứng dụng của mình, sau đó nhấn một URL khác để dừng lập hồ sơ và ghi tệp thống kê.

+0

Tôi đã thử điều này, quá, nhưng tôi thấy điều này không giúp gì nhiều hơn bình-debugtoolbar nào (ít nhất là về render jinja2). – akai

Các vấn đề liên quan