I have a large code base, and something is now taking too long to execute. I have no idea what.
The code never raises an exception, it just appears to keep on processing something.
What I’d like to do is place timers around some functions to test which one is the culprit. But I’m not sure if that is the right approach, or how to do it.
I can’t easily raise exceptions at points around the code, because there are various loops that call the same functions, that perhaps only sometimes take too long.
What is the best strategy?
One solution is to use
cProfile, which comes built into Python, to tell what functions your code is spending the most time in. Critically, this profiling works even if you stop your code with aKeyboardInterrupt. Thus, you can start your code running and profiling, stop it after a minute or two, and then see where it was spending its time.Run your code with these extra
-mand-oarguments:and then once the program has finished running, run the following code (from another script, for example):
This will print a list of the functions sorted by the total time you spent in them.
Here’s a demonstration of using profiling to debug an infinite loop. Let’s say
myscript.pyhad the following code.Of course this causes an infinite loop- g will be run many, many times. So I run the profiling command above, but then I stop it after about 30-40 seconds (could be much shorter even). Its profile will then be printed as:
Notice that our infinitely looping function
gis right at the top of the list in terms of time spent in the function.Note: Just because the code is spending all its time in one function doesn’t mean that the loop is directly around that function- it could be called by a function that is called by a function (etc) that is in an infinite loop (notice that
appendis near the top of the list since it is called insideg). One alternative trick is to sort them according to the cumulative time spent in each function, using.sort_stats("cum"). A combination of these two approaches, along with a little detective work (looking at the code and adding debug messages), should be able to identify the culprit.