Профилирующие генераторы Python - PullRequest
9 голосов
/ 26 августа 2010

Я адаптирую приложение, которое интенсивно использует генераторы для получения своих результатов, для предоставления веб-интерфейса web.py.

До сих пор я мог обернуть вызов для цикла for и операторов, производящих вывод, в функцию и вызвать ее с помощью cProfile.run() или runctx(). Концептуально:

def output():
    for value in generator():
        print(value)

cProfile.run('output()')

В web.py мне нужно обернуть его следующим образом, так как я хочу немедленно выводить результаты потенциально длительных вычислений на каждом шаге итерации, используя yield:

class index:
    def GET(self):
        for value in generator():
            yield make_pretty_html(value)

Есть ли способ профилировать все вызовы генератора, как в первом примере, когда он используется, как во втором?

Ответы [ 3 ]

5 голосов
/ 11 сентября 2010

Я наконец нашел решение. Возвращаемое значение профилирования через здесь .

import cProfile
import pstats
import glob
import math

def gen():
    for i in range(1, 10):
        yield math.factorial(i)

class index(object):
    def GET(self):
        p = cProfile.Profile()

        it = gen()
        while True:
            try:
                nxt = p.runcall(next, it)
            except StopIteration:
                break
            print nxt

        p.print_stats()

index().GET()

Я также могу объединить несколько таких результатов профилирования (как только я начну давать уникальные имена файлов) через документацию и хранить / анализировать их вместе.

1 голос
/ 10 сентября 2010

Похоже, вы пытаетесь профилировать каждый вызов на «следующий» на генераторе? Если это так, вы можете обернуть ваш генератор в генератор профилирования. Примерно так: закомментированная часть будет отправлять результаты в журнал или базу данных.

def iter_profiler(itr):
  itr = iter(itr)
  while True:
    try:
      start = time.time()
      value = itr.next()
      end = time.time()
    except StopIteration:
      break
    # do something with (end - stop) times here
    yield value

Тогда вместо того, чтобы создавать экземпляр вашего генератора как generator(), вы бы использовали iter_profiler(generator())

0 голосов
/ 26 августа 2010

Можете ли вы просто использовать time.time () для профилирования интересующих вас деталей? Просто получите текущее время и вычтите из последнего раза, когда вы сделали измерение.

...