Размер памяти Python - PullRequest
       5

Размер памяти Python

0 голосов
/ 31 декабря 2010

Если у меня есть список чисел и если я использую словарь с использованием одного и того же, занимают ли они оба одно и то же место в памяти?

Например.

list = [[0,1],[1,0]]
dict = {'0,0' = 0 , '0,1' = 1, '1,0' = 1, '1,1' = 0 }

будет ли размер памяти list и dict одинаковым?который займет больше места?

Ответы [ 4 ]

3 голосов
/ 31 декабря 2010

Если вы используете Python 2.6 или выше, вы можете использовать sys.getsizeof () , чтобы выполнить тест

>>> import sys
>>> aList = [[0,1],[1,0]]
>>> aDict = {'0,0' : 0 , '0,1' : 1, '1,0' : 1, '1,1' : 0 }
>>> sys.getsizeof(aList)
44
>>> sys.getsizeof(aDict)
140

В приведенном вами примере мы видим, что aDict занимает больше места в памяти.

1 голос
/ 31 декабря 2010

Короче говоря, они не будут одинаковыми.Список должен работать лучше, если только вы не можете иметь малонаселенные списки, которые могли бы быть реализованы в dict.

Как уже упоминалось несколькими другими, getsizeof не суммирует содержащиеся объекты.

Вот рецепт, который работает для вас на стандартных типах Python (3.0).

Вычислить объем памяти, занимаемой объектом и его содержимым

Используя этот рецепт на python 3.1, можно привести следующие результаты:

aList = [[x,x] for x in range(1000)]
aListMod10 = [[x%10,x%10] for x in range(1000)]
aTuple = [(x,x) for x in range(1000)]
aDictString = dict(("%s,%s" % (x,x),x) for x in range(1000))
aDictTuple = dict(((x,x),x) for x in range(1000))

print("0", total_size(0))
print("10", total_size(10))
print("100", total_size(100))
print("1000", total_size(1000))

print("[0,1]", total_size([0,1]))
print("(0,1)", total_size((0,1)))

print("aList", total_size(aList))
print("aTuple", total_size(aTuple))
print("aListMod10", total_size(aListMod10))
print("aDictString", total_size(aDictString))
print("aDictTuple", total_size(aDictTuple))

print("[0]'s", total_size([0 for x in range(1000)]))
print("[x%10]'s", total_size([x%10 for x in range(1000)]))
print("[x%100]'s", total_size([x%100 for x in range(1000)]))
print("[x]'s", total_size([x for x in range(1000)]))

Вывод:

0 12
10 14
100 14
1000 14

[0,1] 70
(0,1) 62

aList 62514
aTuple 54514
aListMod10 48654
aDictString 82274
aDictTuple 74714

[0]'s 4528
[x%10]'s 4654
[x%100]'s 5914
[x]'s 18514

Похоже, логически следует, что наиболее эффективным вариантом памяти было бы использование 2 списков:

list_x = [0, 1, ...]
list_y = [1, 0, ...]

Это может стоить того, только если у вас мало памяти иОжидается, что список будет большим.Я бы предположил, что шаблон использования будет создавать (x, y) кортежи повсюду в любом случае, так что может случиться так, что вы действительно должны просто сделать:

tuples = [(0, 1), (1, 0), ...]

При всех равных условиях, выберите то, что позволяетвам написать наиболее читаемый код.

1 голос
/ 31 декабря 2010

Получить размер объектов в python сложно.Якобы, это можно сделать с помощью sys.getsizeof, но он возвращает неполные данные.

В моей системе используется пустой список размером 32 байта.

>>> sys.getsizeof([])
32

Список с одним элементом имеетразмер 36 байт.Кажется, это не зависит от элемента.

>>> sys.getsizeof([[1, 2]])
36
>>> sys.getsizeof([1])
36

Так что вам также необходимо знать размер внутреннего списка.

>>> sys.getsizeof([1, 2])
40

Таким образом, ваше использование памяти дляlist (при условии, что он совпадает с моей системой) должен быть 32 байта плюс 44 байта для каждого внутреннего списка.Это потому, что python хранит накладные расходы, связанные с хранением списка, который стоит 32 байта.Каждая дополнительная запись представляется как указатель на этот объект и стоит 4 байта.Таким образом, указатель стоит 4 байта поверх того, что вы храните.В случае двух списков элементов это 40 байтов.

Для dict это 136 для пустого dict

>>> sys.getsizeof({})
136

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

>>> sys.getsizeof({1: 2})
136
1 голос
/ 31 декабря 2010

Вероятность того, что словарь будет больше, очень велика.

Словарь и список - это довольно разные структуры данных.Когда он сводится к памяти и инструкциям процессора, список довольно прост: все значения в нем являются смежными, и когда вы хотите получить доступ к элементу n, вы переходите в начало списка, перемещаете элементы n вперед,и верни это.Это легко, потому что элементы списка являются смежными и имеют целочисленные ключи.

С другой стороны, ограничения для словарей довольно разные.Вы не можете просто перейти к началу словаря, переместить элемент key вперед и вернуть его, потому что key может просто не быть числовым.Кроме того, ключи не обязательно должны быть смежными.

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

По совпадению, оба могут иметь одинаковый размер, хотя это было бы удивительно.Однако представление данных будет другим, несмотря ни на что.

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