Is there any way to do "conditional profiling" with cProfile
? I have a method, let's call it readPackets()
, which is supposed to take only a few milliseconds at most, but every once in a while it takes 0.5 second or more. (The issue involves multithreaded Python access... I assume something else has the GIL or is competing for some lock, but I don't know what.)
What I want to do is profile it only when it takes a long time -- I can already do something like this:
pr = cProfile.Profile()
class MyEngine(object):
def run(self):
while self.alive:
# in main event loop
pr.enable()
self.readPackets()
pr.disable()
...
# other stuff
and that gets me a nice profile of what's running inside readPackets in general, but these slowdowns are somewhat rare, and it's really hard to tell what's going on in that one instance.
What I really want is something like this:
pr = cProfile.Profile()
class MyEngine(object):
def run(self):
while self.alive:
# in main event loop
transaction = pr.beginTransaction()
t0 = time.time()
pr.enable()
self.readPackets()
pr.disable()
t1 = time.time()
if (t1 - t0) > 0.5:
transaction.commit() # Found a slow execution!
else:
transaction.rollback() # it's fast, ignore it
...
# other stuff
or this:
class MyEngine(object):
def run(self):
while self.alive:
# in main event loop
t0 = time.time()
pr.enable()
self.readPackets()
pr.disable()
t1 = time.time()
if (t1 - t0) < 0.5:
pr.clear() # get rid of this iteration, we don't care
else:
sys.exit() # got a slow iteration ...
# other stuff
Is there any way to profile a single call to a method, but only keep the results if it's slow?