Как sys.getsizeof работает под капотом? - PullRequest
1 голос
/ 03 апреля 2019

Я проверял функцию sys.getsizeof, и я знаю, что она возвращает размер в байтах передаваемого параметра.

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

Примечание: Я использую Python 3.7.3 в macOS для запуска следующего:

Для номеров

>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
28
>>> sys.getsizeof(-1)
28
>>> sys.getsizeof(1.0)
24
>>> sys.getsizeof(-1.0)
24

Для списков

>>> sys.getsizeof([])
64
>>> sys.getsizeof([1])
72
>>> sys.getsizeof([1.0])
72
>>> sys.getsizeof([0, 1])
80

Для строк

>>> sys.getsizeof('d')
50
>>> sys.getsizeof('do')
51

Для словарей

>>> sys.getsizeof({})
240
>>> sys.getsizeof({'a': 1})
240
>>> sys.getsizeof({'a': 1, 'b': 2})
240
>>> sys.getsizeof({'a': 1, 'b': 2, 'c': 3, 'd': 4})
240

Я не понимаю , почему размер 0 меньше других целых чисел . Несмотря на то, что я могу определить шаблон при добавлении большего количества элементов в список или строку, но я не понимаю , почему размер словаря одинаков независимо от числа пар «ключ-значение», которые он имеет .

1 Ответ

1 голос
/ 03 апреля 2019

Я не понимаю, почему размер 0 меньше, чем у других целых чисел.

Я предполагаю, что целочисленные объекты хранят количество int с, необходимое для представления целого числа, за которым следует столько int с. Таким образом, 0 будет меньше, чем другие числа, потому что он может быть представлен с 0 int с. Следовательно, размер снова увеличится, как только вы доберетесь до чисел, которые не помещаются в один int.

Я не понимаю, почему размер словаря одинаков, независимо от того, какое количество пар ключ-значение у него есть.

Для dict s это, вероятно, связано с тем, что размер массива в хэш-карте (как у Python dict s) больше, чем количество элементов. Обычно он начинается с некоторого размера по умолчанию и затем удваивается при достижении заданного порога (например, когда он заполнен, скажем, на 70%). Как только вы доберетесь до определенного количества элементов, вы увидите, что размер увеличится.

Вы будете наблюдать аналогичное поведение со списками, если будете создавать их путем многократного добавления к ним, а не создания списка определенного размера для начала. То есть, если вы начнете с пустого списка, а затем добавляете его в цикле, печатая размер после каждого добавления, вы увидите, что размер будет увеличиваться только в несколько раз. Это связано с тем, что размер базового массива не будет изменяться при каждом добавлении, вместо этого его размер будет удваиваться всякий раз, когда он будет заполнен, поэтому время между его изменением будет удваиваться после каждого изменения размера (что дает добавленное амортизированное время O (1) вместо O (п)).

...