TGViewer
Oh My Py Oh My Py @ohmypy · 2.26K subscribers
Post #150 3.14K
Компактные объекты

Питон — объектный язык. Это здорово и удобно, пока не придется создать 10 млн объектов в памяти, которые благополучно ее и съедят. Поговорим о том, как уменьшить аппетит.

Допустим, есть у вас простенький объект «питомец» с атрибутами «имя» (строка) и «стоимость» (целое). Интуитивно кажется, что самое компактное предоставление — в виде кортежа:

("Frank the Pigeon", 50000)


Замерим, сколько займет в памяти один такой красавчик:

def fields():
# генерит name длины 10
# и price до 100К
# ...
return (name, price)

n = 10_000
pets = [fields() for _ in range(n)]
size = round(asizeof(pets) / n)
print(f"Pet size (tuple) = {size} bytes")


Pet size (tuple) = 161 bytes


161 байт. Будем использовать как основу для сравнения.

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

@dataclass
class PetData:
name: str
price: int


А что у него с размером?

Pet size (dataclass) = 257 bytes
x1.60 to baseline


Ого, какой толстенький!

Попробуем использовать именованный кортеж:

class PetTuple(NamedTuple):
name: str
price: int


Pet size (named tuple) = 161 bytes
x1.00 to baseline


Теперь вы понимаете, за что я его так люблю. Удобный интерфейс как у датакласса — а вес как у кортежа. Идеально.

Или нет? В Python 3.10 приехали датаклассы со слотами:

@dataclass(slots=True)
class PetData:
name: str
price: int


Pet size (slots dataclass) = 153 bytes
x0.95 to baseline


Ого! Магия слотов создает специальные худощавые объекты, у которых внутри нет словаря, в отличие от обычных питонячих объектов. И такой датакласс ничуть не уступает кортежу.

Что делать, если 3.10 вам еще не завезли? Использовать NamedTuple. Или прописывать слоты вручную:

@dataclass
class PetData:
__slots__ = ("name", "price")
name: str
price: int


У слотовых объектов есть свои недостатки. Но они отлично подходят для простых случаев (без наследования и прочих наворотов).

P.S. Конечно, настоящий победитель — numpy-массив. Но с ним неинтересно соревноваться ツ

песочница

#stdlib
  • 👍 61
  • 🔥 11
More from @ohmypy
  1. Apr 4, 2023ChatGPT-бот: группы, внешние ссылки, шорткаты Сделать GPT-бота легко, а вот удобного GPT-б…
  2. Mar 11, 2023ChatGPT-бот на Python Последние месяцы поставили рекорд по количеству программ, интегриров…
  3. Aug 3, 2022JSON Lines На днях узнал про формат JSON Lines. Это такой CSV на стероидах: — каждая запис…
  4. Jul 18, 2022Попробуйте Go Чем больше я узнаю Python, тем больше мне нравится Go. Альберт Эйнштейн Нет,…
  5. Jun 1, 2022Многозначительное многоточие Не знаю, заметили вы или нет в посте о протоколах. Не самая и…
  6. May 31, 2022Через протокол Цитата выше взята из PEP 544 (Python Enhancement Proposal, предложение о до…
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 →