NamedTuple, dataclass, attrs, msgspec — все решают одну задачу, но с очень разной стоимостью при старте программы. Автор сделал детальный бенчмарк. Вот что получилось.
📊 Три уровня производительности (warm start)
Быстрые (~7-12 µs на тип):
— native slots — просто
__slots__ — msgspec.Struct — сериализация + struct в одном
— record-type (C) — прототип C-расширения
Средние (~76-96 µs, в ~8 раз медленнее):
— NamedTuple — то что большинство использует по умолчанию
— record-type — декоратор от Brett Cannon
Медленные (~200-370 µs, в ~20-30 раз медленнее):
— dataclass, frozen dataclass
— attrs
🔍 Почему такая разница
Всё упирается в количество методов которые генерируются при создании типа:
— native slots и C-расширения: ничего не генерируют → быстро
— NamedTuple: генерирует один
__new__ через eval → средне— dataclass: генерирует
__init__, __repr__, __eq__ за один раз, frozen добавляет ещё три → медленно💾 Память на экземпляр
native slots → 64 байта
NamedTuple → 88 байт (tuple overhead)
msgspec → 64 байта
attrs → 80 байт
dataclass → 64 байта
frozen=True не меняет размер в памяти — это только флаг на уровне записи, не структуры.
⚡ Время создания экземпляра
msgspec → ~62 ns
native → ~87 ns
NamedTuple → ~138 ns
attrs → ~209 ns
frozen dc → ~224 ns
Если пишете CLI или инструменты где важен startup time — NamedTuple не такой «бесплатный» как кажется. msgspec быстрее после ~229 типов (warm) но тянет за собой 19ms импорта. Для большинства проектов NamedTuple всё ещё разумный выбор — но теперь вы знаете цену.
📍 Навигация: Вакансии • Задачи • Собесы
Библиотека питониста
#буст