TGViewer
Интересное что-то Интересное что-то @youknowds · 625 subscribers
Post #11613 139

Forwarded from DziS Science | Data Science

Привет всем!👋

Сегодня поговорим про небольшую оптимизацию кода по памяти.
Известный факт, что неизменяемые структуры, которые имеют фиксированные размеры, имеют некоторые преимущества в сравнении с изменяемыми.
В рамках проектов, где часто вызываются миллионы мелких объектов (например, узлы в графе, события в симуляции, кастомные токены) проблема утечки памяти встает очень остро. Отчасти, это касается и атрибутов объектов.

По умолчанию 🐍 хранит атрибуты объектов в словаре, включенном в метод __dict__ (появился он в языке 8 февраля 2012 года), который, как и обычный словарь имеет динамическое выделение памяти и может быть расширяем, что при всех своих плюсах создает большую нагрузку на память.

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

Рассмотрим на примере:
🔸Определим классический класс CoordinatesDict`и класс `CoordinatesSlots с использованием __slots__
import sys

class CoordinatesDict:
def __init__(self, x, y,z):
self.x = x
self.y = y
self.z = z

class CoordinatesSlots:
__slots__ = ['x', 'y', 'z'] # Фиксируем атрибуты
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z


🔸Теперь определим объекты классов obj1 и obj2:
obj1 = CoordinatesDict(1, 2, 3)
obj2 = CoordinatesSlots(1, 2, 3)


- Какие разницы в этих объектах?
🔵В obj1 можно дополнительно объявить новый атрибут, скажем, dist и присвоить ему значение, он пополнит ряды __dict__. В obj2 аналогичная операция вернет AttributeError
Пример:
obj1.dist = 2
obj1.__dict__

>>>{'x': 1, 'y': 2, 'z': 3, 'dist': 2}

obj2.dist = 2

>>>AttributeError: 'CoordinatesSlots' object has no attribute 'dist'

Причина такого поведения лежит именно в формировании класса с использованием __slots__. Такой класс, как говорилось ранее, хранит атрибуты в массиве фиксированной размерности, отключая возможность работы со словарем атрибутов (то есть у вас не появляется __dict__), а все атрибуты, не записанные в массив, поднимают ошибку.

🔵В obj2 нет словаря атрибутов __dict__, а следовательно на него не требуется память.
Проверить это просто:
print(sys.getsizeof(obj1), sys.getsizeof(obj1.__dict__)) 
print(sys.getsizeof(obj2))
print(sys.getsizeof(obj2.__dict__))

Вывод следующий (до добавления атрибута):
48 272
56
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipython-input-390784945.py in <cell line: 0>()
18 print(sys.getsizeof(p1), sys.getsizeof(p1.__dict__))
19 print(sys.getsizeof(p2))
---> 20 print(sys.getsizeof(p2.__dict__))

AttributeError: 'CoordinatesSlots' object has no attribute '__dict__'


Таким образом, если мы имеет часто используемый класс и нам не нужна свобода в изменении состава атрибутов, то правильнее использовать конструкцию со __slots__



Ставь 🔥, если не знал.
Ставь👍, если знал.

#ds_лайфхаки
More from @youknowds
  1. Sep 24, 2026https://www.youtube.com/watch?v=ZpL3QsO5A9U Спокойное, неторопливое и глубокое видео для т…
  2. Sep 24, 2026#interview #career
  3. Sep 23, 2026Halo: почти год моей работы в White Circle теперь в опенсорсе Почти год я веду в White Cir…
  4. Sep 23, 2026#llm #gpu
  5. Sep 23, 2026Постоянная рубрика: "блекпилл недели (и как с ним быть)" После предыдущего болезненного оп…
  6. Sep 23, 2026#agents #code
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →