perfilar un método de una clase en Python usando cprofile?
Pregunta
Me gustaría perfilar un método de una función en Python, utilizando cprofile. He intentado lo siguiente:
import cProfile as profile
# Inside the class method...
profile.run("self.myMethod()", "output_file")
Pero no funciona. ¿Cómo puedo llamar a un self.método con "correr"?
Solución
Utilice los profilehooks decorador
Otros consejos
EDIT:. En este momento, no se dio cuenta de que la llamada era de perfil en un método de clase
run
simplemente intenta exec
la cadena que se pasa. Si self
no está obligado a nada en el ámbito de la perfilador está utilizando, no se puede utilizar en run
! Utilice el método runctx
para pasar en las variables locales y globales en el ámbito de la llamada a la perfilador:
>>> import time
>>> import cProfile as profile
>>> class Foo(object):
... def bar(self):
... profile.runctx('self.baz()', globals(), locals())
...
... def baz(self):
... time.sleep(1)
... print 'slept'
... time.sleep(2)
...
>>> foo = Foo()
>>> foo.bar()
slept
5 function calls in 2.999 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 2.999 2.999 <stdin>:5(baz)
1 0.000 0.000 2.999 2.999 <string>:1(<module>)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
2 2.999 1.499 2.999 1.499 {time.sleep}
Aviso de la última línea:. time.sleep
es lo que está tomando el tiempo
Yo no recomendaría el perfil de una única rutina, porque eso implica saber de antemano que hay un problema allí.
Un aspecto fundamental de los problemas de rendimiento es que son furtivo. No están donde piensan que son, porque si lo fueran como quieren que ellos ya resuelto.
Es mejor correr todo el programa con una carga de trabajo realista y dejar que la técnica de perfiles le diga dónde están los problemas.
He aquí un ejemplo donde perfiles de los hallazgos problema, y ??se espera que no se donde.
Si su función bajo valor vuelve perfil (s), tiene que cambiar la excelente respuesta de @katrielalex ligeramente:
... profile.runctx('val = self.baz()', globals(), locals())
... print locals()['val']