I've recently become interested in algorithms and have begun exploring them by writing a naive implementation and then optimizing it in various ways.
I'm already familiar with the standard Python module for profiling runtime (for most things I've found the timeit magic function in IPython to be sufficient), but I'm also interested in memory usage so I can explore those tradeoffs as well (e.g. the cost of caching a table of previously computed values versus recomputing them as needed). Is there a module that will profile the memory usage of a given function for me?
This one has been answered already here: Python memory profiler
Basically you do something like that (cited from Guppy-PE):
Python 3.4 includes a new module:
tracemalloc
. It provides detailed statistics about which code is allocating the most memory. Here's an example that displays the top three lines allocating memory.And here are the results:
When is a memory leak not a leak?
That example is great when the memory is still being held at the end of the calculation, but sometimes you have code that allocates a lot of memory and then releases it all. It's not technically a memory leak, but it's using more memory than you think it should. How can you track memory usage when it all gets released? If it's your code, you can probably add some debugging code to take snapshots while it's running. If not, you can start a background thread to monitor memory usage while the main thread runs.
Here's the previous example where the code has all been moved into the
count_prefixes()
function. When that function returns, all the memory is released. I also added somesleep()
calls to simulate a long-running calculation.When I run that version, the memory usage has gone from 6MB down to 4KB, because the function released all its memory when it finished.
Now here's a version inspired by another answer that starts a second thread to monitor memory usage.
The
resource
module lets you check the current memory usage, and save the snapshot from the peak memory usage. The queue lets the main thread tell the memory monitor thread when to print its report and shut down. When it runs, it shows the memory being used by thelist()
call:If you're on Linux, you may find
/proc/self/statm
more useful than theresource
module.maybe it help:
<see additional>
I you only want to look at the memory usage of an object, (answer to other question)
Since the accepted answer and also the next highest voted answer have, in my opinion, some problems, I'd like to offer one more answer that is based closely on Ihor B.'s answer with some small but important modifications.
This solution allows you to run profiling on either by wrapping a function call with the
profile
function and calling it, or by decorating your function/method with the@profile
decorator.The first technique is useful when you want to profile some third-party code without messing with its source, whereas the second technique is a bit "cleaner" and works better when you are don't mind modifying the source of the function/method you want to profile.
I've also modified the output, so that you get RSS, VMS, and shared memory. I don't care much about the "before" and "after" values, but only the delta, so I removed those (if you're comparing to Ihor B.'s answer).
Profiling code
Example usage, assuming the above code is saved as
profile.py
:This should result in output similar to the below:
A couple of important final notes:
profile(my_function, arg)
to profilemy_function(arg)
For a really simple approach try:
Just insert
using("Label")
where you want to see what's going on.