如何使用类方法使用memory_profiler(python模块)?

时间:2013-05-16 16:55:03

标签: python methods profiling memory-profiling functools

我想描述类方法的时间和内存使用情况。我没有找到一个开箱即用的解决方案(有这样的模块吗?),我决定使用timeit进行时间分析,memory_usage来自memory_profiler模块。

我遇到了使用memory_profiler分析方法的问题。我尝试过不同的变种,但都没有。

当我尝试使用functools中的部分时,我收到此错误:

File "/usr/lib/python2.7/site-packages/memory_profiler.py", line 126, in memory_usage
  aspec = inspect.getargspec(f)
File "/usr/lib64/python2.7/inspect.py", line 815, in getargspec
  raise TypeError('{!r} is not a Python function'.format(func))
TypeError: <functools.partial object at 0x252da48> is not a Python function

顺便说一句,完全相同的方法适用于timeit函数。

当我尝试使用lambda时,我收到了此错误:

File "/usr/lib/python2.7/site-packages/memory_profiler.py", line 141, in memory_usage
  ret = parent_conn.recv()
IOError: [Errno 4] Interrupted system call

如何使用memory_profiler处理类方法?

PS:我有内存分析器(0.26)(用pip安装)。

UPD:这实际上是错误。您可以在此处查看状态:https://github.com/fabianp/memory_profiler/issues/47

1 个答案:

答案 0 :(得分:5)

如果要查看分配给Python VM的内存更改,可以使用psutil。这是一个使用psuil的简单装饰器,它将打印内存中的变化:

import functools
import os
import psutil


def print_memory(fn):
    def wrapper(*args, **kwargs):
        process = psutil.Process(os.getpid())
        start_rss, start_vms = process.get_memory_info()
        try:
            return fn(*args, **kwargs)
        finally:
            end_rss, end_vms = process.get_memory_info()
            print((end_rss - start_rss), (end_vms - start_vms))
    return wrapper


@print_memory
def f():
    s = 'a'*100

很可能,您将看到的输出将表示内存没有变化。这是因为对于小分配,Python VM可能不需要从OS请求更多内存。如果你分配一个大型数组,你会看到不同的东西:

import numpy
@print_memory
def f():
    return numpy.zeros((512,512))

在这里,您应该看到内存发生了一些变化。

如果你想看看每个分配的对象使用了多少内存,我所知道的唯一工具是heapy

In [1]: from guppy import hpy; hp=hpy()

In [2]: h = hp.heap()

In [3]: h
Out[3]: 
Partition of a set of 120931 objects. Total size = 17595552 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0  57849  48  6355504  36   6355504  36 str
     1  29117  24  2535608  14   8891112  51 tuple
     2    394   0  1299952   7  10191064  58 dict of module
     3   1476   1  1288416   7  11479480  65 dict (no owner)
     4   7683   6   983424   6  12462904  71 types.CodeType
     5   7560   6   907200   5  13370104  76 function
     6    858   1   770464   4  14140568  80 type
     7    858   1   756336   4  14896904  85 dict of type
     8    272   0   293504   2  15190408  86 dict of class
     9    304   0   215064   1  15405472  88 unicode
<501 more rows. Type e.g. '_.more' to view.>

我很长时间没有使用它,所以我建议尝试并阅读文档。请注意,对于使用大量内存的应用程序,计算此信息的速度可能非常慢。