Объем памяти, который тратит набор Python, увеличивается пошагово - PullRequest
0 голосов
/ 16 октября 2018

Я провожу эксперимент с тем, сколько памяти тратит каждый из типов массивов Python, а это list, tuple, set, dict, np.array.Тогда я получил следующий результат.

The amount of memory Python array types spend

(ось x - длина массива, ось y - объем памяти.)

Я обнаружил, что объем памяти, который тратит Python set, увеличивается пошагово (также dict), тогда как объем памяти других увеличивается линейно, как я и ожидал.Интересно, что отличает их?

Я использовал следующую get_size() функцию.( ссылка )

def get_size(obj, seen = None):
    size = sys.getsizeof(obj)
    if seen is None:
        seen = set()
    obj_id = id(obj)
    if obj_id in seen:
        return 0
    seen.add(obj_id)
    if isinstance(obj, dict):
        size += sum([get_size(v, seen) for v in obj.values()])
        size += sum([get_size(k, seen) for k in obj.keys()])
    elif hasattr(obj, '__dict__'):
        size += get_size(obj.__dict__, seen)
    elif hasattr(obj, '__iter__') and not isinstance(obj, (str, bytes, bytearray)):
        size += sum([get_size(i, seen) for i in obj])
    return size

И я измерил память от длины 0 до 10000 с интервалом в 100 интервалов.

мой код: https://repl.it/repls/WanEsteemedLines

1 Ответ

0 голосов
/ 05 ноября 2018

CPython устанавливает и использует всегда внутреннюю хеш-таблицу с размером двух степеней.list, tuple и numpy.ndarray обладают большей гибкостью в отношении размера своего базового буфера памяти, но set и dict жестко заданы для использования размеров таблицы со степенью двойки.Реализация не может функционировать с размером таблицы не равной двум.См. Objects/dictobject.c и Objects/setobject.c.

Скачки на вашем графике происходят, когда размер таблицы переходит на новую степень двойки.

Кстати, ваш get_size работает не очень хорошо.Например, у него есть две ошибки, влияющие на случай numpy.ndarray, которые почти сводятся на нет (но не совсем).Он пытается добавить размеры элементов массива NumPy к размеру всего массива, но для массива NumPy размеры элементов уже учитываются getsizeof.Кроме того, он определяет идентичность объекта с помощью id, но объекты, созданные путем итерации по массиву NumPy, создаются на лету и сразу же умирают, поэтому их значения id не являются уникальными.На практике это, вероятно, приводит к превышению размера в один или два раза размера объектов, представляющих элементы массива.

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