Я нашел Gprof2Dot чрезвычайно полезным. Вывод модулей профилирования, которые я пытался интерпретировать как довольно не интуитивно понятный.
Gprof2Dot превращает вывод cProfile в симпатичный график с выделением самой медленной цепочки (?) И небольшим количеством информации о каждой функции (имя функции, процент времени, потраченного на эту функцию, и количество вызовов).
Пример графика (1429x1896px)
Я не так много сделал с App Engine, но при профилировании сценариев, не относящихся к веб-приложениям, я склонен профилировать сценарий, который запускает все тесты юнитов, что может быть не очень точно в реальных ситуациях
Один (лучше?) Метод - иметь скрипт, который выполняет ложный запрос 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()
, например, приведенную ниже:
<code>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 "
»
[...]
Чтобы включить профилирование в вашем приложении, установите main = profile_main
. Чтобы запустить ваше приложение как обычно, просто установите main = real_main
.