Как мне профилировать время запуска `paster serve`? - PullRequest
2 голосов
/ 09 ноября 2009

Python's paster serve app.ini занимает больше времени, чем я хотел бы быть готовым к первому запросу.

Я знаю, как профилировать запросы с помощью промежуточного программного обеспечения, но как мне профилировать время инициализации? Мне бы хотелось, чтобы он не создавал пул потоков и выходил, как только он готов к работе, поэтому время после его завершения не отображается в профиле.

Ответы [ 3 ]

1 голос
/ 09 ноября 2009

Даже если вы профилируете это - я сомневаюсь, что вы получите много подсказок для оптимизации.

Мы используем Paster в настройке mod_wsgi, чтобы уменьшить время запуска, чтобы пользователь не страдал от него, и убедиться, что, например, Чтобы правильно настроить виджеты, мы делаем это:

app = paste.fixture.TestApp(application)
# TODO-dir: FIXME, must go away!
try:
    app.get("/")
except:
    pass

Здесь приложение, конечно, является инициализированным / загруженным приложением для пастера.

1 голос
/ 10 ноября 2009

Я почти всегда использую paster serve --reload ... во время разработки. Эта команда выполняется как подпроцесс (она выполняет свой собственный скрипт с использованием модуля subprocess, а не fork()).

Подпроцесс опрашивает изменения исходного кода, завершает работу при обнаружении изменения и перезапускает родительский элемент paster serve --reload.

То есть, если вы собираетесь профилировать paster serve, пропустите аргумент --reload. Профилирование отдельных запросов с помощью промежуточного программного обеспечения должно работать в любом случае.

Моя особая проблема заключалась в том, что pkg_resources занимает время, пропорциональное всем установленным пакетам, когда он запускается впервые. Я решил это, перестроив свой virtualenv без ненужных пакетов.

1 голос
/ 09 ноября 2009

В целом ваша методология может заключаться в том, чтобы делать временные блоки вокруг разделов кода, а затем выдавать операторы журналирования. Что касается выключения после init, я не знаком со спецификой того, что вы используете.

Edit: я использовал это промежуточное программное обеспечение, чтобы помочь мне найти провалы производительности. В настоящее время это промежуточное программное обеспечение werkzeug, вы можете адаптировать его для своего использования. Надеюсь, это поможет

<code>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
'% to_unicode (out.getvalue ())] response.content_type = 'text / html'
...