Как я могу профилировать память многопоточной программы на Python? - PullRequest
8 голосов
/ 26 января 2011

Есть ли способ профилировать память многопоточной программы на Python?

Для профилирования ЦП я использую cProfile для создания отдельных характеристик профилировщика для каждого потока и их последующего объединения. Однако я не смог найти способ сделать это с помощью профилировщиков памяти. Я использую heapy.

Есть ли способ комбинировать статистику в куче, как cProfile? Или какие другие профилировщики памяти вы бы предложили, которые больше подходят для этой задачи.

Был задан связанный вопрос для профилирования использования ЦП в многопоточной программе: Как я могу профилировать многопоточную программу на Python?

Также еще один вопрос относительно профилировщика памяти:

Профилировщик памяти Python

Ответы [ 4 ]

7 голосов
/ 14 февраля 2011

Если вы предпочитаете профилировать объекты, а не необработанную память, вы можете использовать функцию gc.get_objects(), поэтому вам не нужен собственный метакласс.В более поздних версиях Python sys.getsizeof() также позволит вам выяснить, сколько основной памяти используется этими объектами.

3 голосов
/ 07 февраля 2011

Есть способы получить valgrind для памяти профиля программ на python: http://www.python.org/dev/faq/#can-i-run-valgrind-against-python

1 голос
/ 14 февраля 2011

Хорошо.То, что я искал, похоже, не существует.Итак, я нашел решение - обходной путь для этой проблемы.

Вместо профилирования памяти я буду профилировать объекты.Таким образом, я смогу увидеть, сколько объектов существует в определенное время в программе.Чтобы достичь своей цели, я использовал метаклассы с минимальным изменением уже существующего кода.

Следующий метакласс добавляет очень простую подпрограмму к __init__ и __del__ функциям класса.Подпрограмма для __init__ увеличивает число объектов с таким именем класса на один, а __del__ уменьшается на один.

class ObjectProfilerMeta(type):
    #Just set metaclass of a class to ObjectProfilerMeta to profile object
    def __new__(cls, name, bases, attrs):
        if name.startswith('None'):
            return None

        if "__init__" in attrs:
            attrs["__init__"]=incAndCall(name,attrs["__init__"])
        else:
            attrs["__init__"]=incAndCall(name,dummyFunction)

        if "__del__" in attrs:
            attrs["__del__"]=decAndCall(name,attrs["__del__"])
        else:
            attrs["__del__"]=decAndCall(name,dummyFunction)

        return super(ObjectProfilerMeta, cls).__new__(cls, name, bases, attrs)

    def __init__(self, name, bases, attrs):
        super(ObjectProfilerMeta, self).__init__(name, bases, attrs)


    def __add__(self, other):
        class AutoClass(self, other):
            pass
        return AutoClass

Функции incAndCall и decAndCall используют глобальную переменную модуля, в котором они существуют.

counter={}
def incAndCall(name,func):
    if name not in counter:
        counter[name]=0

    def f(*args,**kwargs):
        counter[name]+=1
        func(*args,**kwargs)

    return f

def decAndCall(name,func):
    if name not in counter:
        counter[name]=0

    def f(*args,**kwargs):
        counter[name]-=1
        func(*args,**kwargs)

    return f

def dummyFunction(*args,**kwargs):
    pass

Функция dummyFunction - это очень простой обходной путь.Я уверен, что есть гораздо лучшие способы сделать это.

Наконец, когда вы хотите увидеть количество существующих объектов, вам просто нужно взглянуть на счетчик словаря.Пример:

>>> class A:
    __metaclass__=ObjectProfilerMeta
    def __init__(self):
        pass


>>> class B:
    __metaclass__=ObjectProfilerMeta


>>> l=[]
>>> for i in range(117):
    l.append(A())


>>> for i in range(18):
    l.append(B())


>>> counter
{'A': 117, 'B': 18}
>>> l.pop(15)
<__main__.A object at 0x01210CB0>
>>> counter
{'A': 116, 'B': 18}
>>> l=[]
>>> counter
{'A': 0, 'B': 0}

Надеюсь, это вам поможет.Это было достаточно для моего случая.

0 голосов
/ 18 февраля 2011

Я использовал Yappi , с которым я добился успеха для нескольких специальных многопоточных корпусов.У него отличная документация, так что у вас не должно возникнуть особых проблем с его настройкой.

Для профилирования памяти обращайтесь к Heapy .Имейте в виду, что он может создать самые большие файлы журналов, которые вы когда-либо видели!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...