profiling un metodo di una classe in Python utilizzando Cprofile?
Domanda
Mi piacerebbe al profilo di un metodo di una funzione in Python, utilizzando Cprofile. Ho provato quanto segue:
import cProfile as profile
# Inside the class method...
profile.run("self.myMethod()", "output_file")
Ma non funziona. Come posso chiamare un self.metodo con "run"?
Soluzione
Con i profilehooks decoratore
Altri suggerimenti
EDIT:. Siamo spiacenti, non si rese conto che la chiamata profilo era in un metodo di classe
run
cerca solo di exec
la stringa si passa. Se self
non è tenuta a qualcosa nel campo di applicazione del profiler che si sta utilizzando, non è possibile utilizzare in run
! Utilizzare il metodo runctx
per passare le variabili locali e globali nel campo di applicazione della chiamata al profiler:
>>> 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}
Si noti l'ultima riga:. time.sleep
è quello che sta prendendo il tempo
non consiglierei il profilo di una singola routine, perché questo implica conoscere in anticipo c'è un problema.
Un aspetto fondamentale dei problemi di prestazioni è che sono subdolo. Non stanno in cui si pensa che sono, perché se fossero di loro si sarebbe risolto già.
E 'meglio per eseguire l'intero programma con un carico di lavoro realistico e lasciare che la tecnica di profilatura dirvi dove sono i problemi.
Ecco un esempio in cui profiling trova il problema, e non è dove previsto.
Se la funzione di sotto del valore di profilo rendimenti (s), è necessario modificare la risposta eccellente da @katrielalex leggermente:
... profile.runctx('val = self.baz()', globals(), locals())
... print locals()['val']