Python的paster serve app.ini
所花費的時間比我想爲第一個請求做好準備要花費更多的時間。如何分析`paster serve`的啓動時間?
我知道如何使用中間件分析請求,但我如何分析初始化時間?我希望它不會分叉一個線程池,並在它準備好提供服務後立即退出,因此準備就緒後的時間不會顯示在配置文件中。
Python的paster serve app.ini
所花費的時間比我想爲第一個請求做好準備要花費更多的時間。如何分析`paster serve`的啓動時間?
我知道如何使用中間件分析請求,但我如何分析初始化時間?我希望它不會分叉一個線程池,並在它準備好提供服務後立即退出,因此準備就緒後的時間不會顯示在配置文件中。
我在開發過程中幾乎總是使用paster serve --reload ...
。該命令將自身執行爲子進程(它使用subprocess
模塊執行自己的腳本,而不是fork()
)。
子進程查詢源代碼更改,當它檢測到更改時退出,並由父級paster serve --reload
重新啓動。
也就是說,如果您要簡介paster serve
本身,請省略--reload
參數。用中間件來分析個別請求應該可以很好地工作。
我特別的問題是pkg_resources
在第一次調用時需要的時間量與所有已安裝的軟件包成比例。我通過重建我的virtualenv解決了這個問題,但沒有不必要的軟件包。
一般而言,您的方法可能是圍繞代碼段執行計時塊,然後發出日誌記錄語句。至於init之後的關閉,我並不熟悉你正在使用的細節。
編輯:我用這個中間件來幫助我找到性能下沉。它目前是一個werkzeug中間件,您可能可以根據您的使用情況進行調整。希望它有幫助
import re
re_profile = re.compile(ur'(^|&|\?)prof($|=|&)')
class ProfilerMiddleware(BaseProcessor):
def process_runner(self, runner, environ):
self.profiler = None
if (environ['REMOTE_ADDR'] in settings_static.internal_ips or settings_static.local_server) and re_profile.match(environ['QUERY_STRING']):
self.profiler = cProfile.Profile()
def wrap(*args, **kwargs):
return self.profiler.runcall(runner, *args, **kwargs)
return wrap
def process_response(self, request, response):
if self.profiler:
self.profiler.create_stats()
out = StringIO.StringIO()
old_stdout, sys.stdout = sys.stdout, out
#from dozer.profile import buildtree, write_dot_graph
#write_dot_graph(self.profiler.getstats(), buildtree(self.profiler.getstats()), "/tmp/output.gv")
self.profiler.print_stats(1)
sys.stdout = old_stdout
response.response = [u'<pre>%s</pre>' % to_unicode(out.getvalue())]
response.content_type = 'text/html'
即使你想要分析它 - 我懷疑你會得到很多提示來優化。
我們在mod_wsgi設置中使用了Paster,並減少了啓動時間,以便用戶不會受到它影響,並確保toscawidgets設置正確,我們這樣做:
app = paste.fixture.TestApp(application)
# TODO-dir: FIXME, must go away!
try:
app.get("/")
except:
pass
這裏的應用是當然的初始化/加載貼紙應用。
我已經在使用profiler來運行'paster',它告訴我哪些方法花費了最多的時間,但輸出結果並不是很有用。我猜這是因爲它產生了工作進程,而剖析器沒有以相同的方式對這些進行剖析。 – joeforker 2009-11-09 16:18:19
我上面發佈的代碼似乎在類似的分支環境中工作得很好,我希望它有幫助。 – 2009-11-09 16:28:15