2021-08-30 13:00:15
Какой тип данных выбрать для оптимального хранения информации? Имеется в виду объем занимаемой памяти.
Можем создать 4 разных варианта объектов и сравнить сколько они занимают оперативки.
Будем создавать простой класс, класс со слотами, именованный кортеж и словарь.
from collections import namedtuple
from sys import getsizeof
NT = namedtuple('NT', 'v1 v2 v3')
class CLASS:
def init(self, x1, x2, x3):
self.v1 = x1
self.v2 = x2
self.v3 = x3
class SLOTS:
slots = ['x1', 'x2', 'x3']
def init(self, x1, x2, x3):
self.x1 = x1
self.x2 = x2
self.x3 = x3
d = dict(x1=1, x2=2, x3=3)
c = CLASS(1, 2, 3)
s = SLOTS(1, 2, 3)
t = NT(1, 2, 3)
Теперь распечатаем что там по памяти
print(' CLS\t\tSLT\t\tDCT\t\tTPL')
print(f'System: {getsizeof(c)}\t\t'
f'{getsizeof(s)}\t\t'
f'{getsizeof(d)}\t\t'
f'{getsizeof(t)}'
)
CLS SLT DCT TPL
System: 48 56 232 64
Хм, в этой статистике обычный класс самый экономный! Но что-то здесь не так. Неужели он экономичней класса со слотами, который рассчитан на скорость и оптимизацию?
Дело в том, что функция
sys.getsizeof() показывает не совсем то что мы ожидаем.
Она берет результат метода __sizeof__ у объекта и добавляет кое-чего от gc.
__sizeof__ возвращает размер, занимаемый данными. Но не учитывает размер обвязки этих данных.
А еще он не гарантирует точность размера типов для third-party расширений.
Для точного измерения размера лучше использовать модуль pympler. Помимо данных он считает сколько места занимает вся структура классов и другая обвязка объекта.
from pympler import asizeof
print(f'Pympler: {asizeof.asizeof(c)}\t\t'
f'{asizeof.asizeof(s)}\t\t'
f'{asizeof.asizeof(d)}\t\t'
f'{asizeof.asizeof(t)}'
)
CLS SLT DCT TPL
Pympler: 416 152 496 160
И вот тут класс со слотами оказывается самым оптимальным решением! И это правильно.
А словарь в этом тесте оказался самый расточительный.
#tricks #libs
929 viewsedited 10:00