Ответ 1
Я нашел Gprof2Dot чрезвычайно полезным. Выходные модули профилирования, которые я пробовал, были довольно неинтуитивными для интерпретации.
Gprof2Dot превращает вывод cProfile в довольно перспективный граф с выделенной самой медленной цепочкой (?) и информацией о каждой функции (имя функции, процент времени на эту функцию и количество вызовов).
Примерный график (1429x1896px)
Я не очень много работал с App Engine, но при профилировании сценариев non-webapp я склонен профилировать script, который запускает все unittests, что может быть не очень точным для реальных ситуаций
Один (лучше?) метод должен иметь script, который выполняет поддельный запрос WSGI, а затем профиль, который.
WSGI - действительно простой протокол, в основном это функция, которая принимает два аргумента: один с информацией о запросе, второй - с функцией обратного вызова (которая используется, например, для настройки заголовков). Возможно, что-то вроде следующего (что возможно - работающий псевдокод)...
class IndexHandler(webapp.RequestHandler):
"""Your site"""
def get(self):
self.response.out.write("hi")
if __name__ == '__main__':
application = webapp.WSGIApplication([
('.*', IndexHandler),
], debug=True)
# Start fake-request/profiling bit
urls = [
"/",
"/blog/view/hello",
"/admin/post/edit/hello",
"/makeanerror404",
"/makeanerror500"
]
def fake_wsgi_callback(response, headers):
"""Prints heads to stdout"""
print("\n".join(["%s: %s" % (n, v) for n, v in headers]))
print("\n")
for request_url in urls:
html = application({
'REQUEST_METHOD': 'GET',
'PATH_INFO': request_url},
fake_wsgi_callback
)
print html
Собственно, документация App Engine объясняет лучший способ профилирования вашего приложения:
Из http://code.google.com/appengine/kb/commontasks.html#profiling:
Чтобы профилировать производительность вашего приложения, сначала переименуйте приложение
main()
вreal_main()
. Затем добавьте новую основную функцию в ваше приложение с именемprofile_main()
, например, следующим:def profile_main(): # This is the main function for profiling # We've renamed our original main() above to real_main() import cProfile, pstats prof = cProfile.Profile() prof = prof.runctx("real_main()", globals(), locals()) print "<pre>" stats = pstats.Stats(prof) stats.sort_stats("time") # Or cumulative stats.print_stats(80) # 80 = how many to print # The rest is optional. # stats.print_callees() # stats.print_callers() print "</pre>"
[...]
Чтобы включить профилирование с вашим приложением, установите
main = profile_main
. Чтобы запустить приложение как обычно, просто установитеmain = real_main
.