The syntax is cProfile. run(statement, filename=None, sort=-1) . You can pass python code or a function name that you want to profile as a string to the statement argument. If you want to save the output in a file, it can be passed to the filename argument.
Python includes a profiler called cProfile. It not only gives the total running time, but also times each function separately, and tells you how many times each function was called, making it easy to determine where you should make optimizations.
Profiling is a technique to figure out how time is spent in a program. With these statistics, we can find the “hot spot” of a program and think about ways of improvement. Sometimes, a hot spot in an unexpected location may hint at a bug in the program as well.
Tracing profilers record every function call your program makes and then print out a report at the end. Sampling profilers take a more statistical approach – they record your program's stack every few milliseconds and then report the results.
EDIT: Sorry, didn't realise that the profile call was in a class method.
run
just tries to exec
the string you pass it. If self
isn't bound to anything in the scope of the profiler you are using, you can't use it in run
! Use the runctx
method to pass in the local and global variables in the scope of the call to the 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}
Notice the last line: time.sleep
is what's taking up the time.
Use the profilehooks decorator
http://pypi.python.org/pypi/profilehooks
If your function under profile returns value(s), you need to change the excellent answer from @katrielalex slightly:
... profile.runctx('val = self.baz()', globals(), locals())
... print locals()['val']
import cProfile
p = cProfile.Profile()
p.runcall(self.myMethod)
p.print_stats()
The Profile
class is documented here.
I wouldn't recommend profiling a single routine, because that implies knowing in advance there's a problem there.
A fundamental aspect of performance problems is they're sneaky. They're not where you think they are, because if they were you would have solved them already.
It's better to run the whole program with a realistic workload and let the profiling technique tell you where the problems are.
Here's an example where profiling finds the problem, and it is not where expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With