Generadores de perfiles de Python

Estoy adaptando una aplicación que hace un uso intensivo de los generadores para producir sus resultados para proporcionar una interfaz web web.py.

Hasta ahora, podría ajustar la llamada al for-loop y las declaraciones que producen salida en una función y llamar a eso utilizando cProfile.run() o runctx() . Conceptualmente:

 def output(): for value in generator(): print(value) cProfile.run('output()') 

En web.py, tengo que ajustarlo de la siguiente manera, ya que quiero producir inmediatamente el resultado del cálculo potencialmente prolongado en cada paso de iteración utilizando el yield :

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

¿Hay una manera de perfilar todas las llamadas al generador como en el primer ejemplo cuando se usa como en el segundo?

Finalmente encontré una solución. Valor de retorno del perfil a través de aquí .

 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() 

También podría combinar varios de estos resultados de perfiles (una vez que empiece a dar nombres de archivos únicos) a través de la documentación y almacenarlos / analizarlos combinados.

¿Parece que estás intentando perfilar cada llamada a ‘siguiente’ en el generador? Si es así, podría envolver su generador en un generador de perfiles. Algo como esto, donde la parte comentada enviará los resultados a un registro o base de datos.

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
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 

Luego, en lugar de crear una instancia de su generador como generator() , usaría iter_profiler(generator())

¿Puedes usar time.time () para perfilar las partes que te interesan? Solo obtenga la hora actual y reste de la última vez que realizó una medición.