Кортежи очень компактны.Наборы основаны на хеш-таблицах и зависят от наличия «пустых» слотов, чтобы снизить вероятность коллизий хеш-функций.
Для достаточно недавней версии CPython, sys._debugmallocstats()
отображает много потенциально интересной информации.Здесь в 64-битном Python 3.7.3:
>>> from sys import _debugmallocstats as d
>>> tups = [tuple("abc") for i in range(1000000)]
tuple("abc")
создает кортеж из 3 1-символьных строк, ('a', 'b', 'c')
.Вот я отредактирую почти все выходные данные:
>>> d()
Small block threshold = 512, in 64 size classes.
class size num pools blocks in use avail blocks
----- ---- --------- ------------- ------------
...
8 72 17941 1004692 4
Так как мы создали миллион кортежей, очень хорошо, что класс размера, использующий блоки 1004692, - тот, который мы хотим ;-) Каждый изблоки потребляют 72 байта.
Вместо этого, вместо этого, вывод показывает, что они потребляют 224 байта каждый, чуть более чем в 3 раза:
>>> tups = [frozenset(t) for t in tups]
>>> d()
Small block threshold = 512, in 64 size classes.
class size num pools blocks in use avail blocks
----- ---- --------- ------------- ------------
...
27 224 55561 1000092 6
В этом конкретном случае другой ответ вамслучайность дает те же результаты:
>>> import sys
>>> sys.getsizeof(tuple("abc"))
72
>>> sys.getsizeof(frozenset(tuple("abc")))
224
Хотя это часто и так, но это не всегда так, потому что объект может потребовать выделения байт больше, чем на самом деле, чтобы удовлетворить выравнивание HWтребования.getsizeof()
ничего об этом не знает, но _debugmallocstats()
показывает количество байтов, которое фактически должен использовать распределитель малых объектов Python.
Например,
>>> sys.getsizeof("a")
50
На32-битный блок, 52 байта фактически необходимо использовать, чтобы обеспечить 4-байтовое выравнивание.В 64-битном боксе в настоящее время требуется 8-байтовое выравнивание, поэтому необходимо использовать 56 байтов.В Python 3.8 (еще не выпущен) для 64-битного блока требуется 16-байтовое выравнивание, и необходимо использовать 64 байта.
Но, игнорируя все это, кортежу всегда потребуется меньше памяти, чемлюбая форма множества с одинаковым количеством элементов - и даже меньше, чем список с таким же количеством элементов.