Профилирующие генераторы Python
Я адаптирую приложение, которое сильно использует генераторы для получения своих результатов, чтобы предоставить веб-интерфейс web.py.
До сих пор я мог привязать вызов к циклу и операторам, производящим вывод в функции, и вызвать их с помощью 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)
Есть ли способ профилировать все вызовы генератору, как в первом примере, когда он использовался как во втором?
Ответы
Ответ 1
Наконец-то я нашел решение. Возвращаемое значение профилирования через здесь.
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()
Я также мог бы объединить несколько таких профилирующих результатов (как только я начну давать уникальные имена файлов) с помощью документации и сохранить/проанализировать их вместе.
Ответ 2
Похоже, вы пытаетесь профилировать каждый вызов на "следующий" на генераторе? Если это так, вы можете обернуть ваш генератор в генератор профилирования. Что-то вроде этого, когда часть с комментариями отправляет результаты в журнал или базу данных.
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())
Ответ 3
Можете ли вы просто использовать time.time() для профилирования интересующих вас частей? Просто получить текущее время и вычесть из последнего раза, когда вы сделали измерение.