TGViewer
About Python [ru] About Python [ru] @python_tesst · 6.45K subscribers
Post #2798 300
⁣Микрооптимизация сериализации в JSON/msgpack: от скрытых словарей до кастомных кодеков

Под high-throughput RPC стандартная сериализация через __dict__ или рефлексию превращается в узкое место. Многие разработчики забывают, что каждый вызов json.dumps или msgpack.packb с объектом по умолчанию парсит всю структуру через __dict__, добавляя лишние накладные расходы.

__slots__: убиваем __dict__ на старте

У обычного класса атрибуты хранятся в __dict__- словаре с хеш-таблицей, замедляющей доступ. __slots__ убирает этот словарь, поля читаются напрямую. Для сериализации это даёт двойной выигрыш: меньше аллокаций при packb/unpackb и более быстрый доступ к значениям.
* Класс с __slots__ занимает меньше памяти, что критично при сотнях тысяч объектов.
* Внутри msgpack можно напрямую читать поля без итерации по __dict__.
* Торгуем гибкостью динамических атрибутов на производительность.
import msgpack

class Point:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y

p = Point(1, 2)
data = msgpack.packb([p.x, p.y], use_bin_type=True) # минимум накладных расходов


__reduce__: явное описание структуры для msgpack

Обычно __reduce__ используют для pickle, но его можно адаптировать под msgpack. Метод возвращает кортеж с идентификатором класса и данными, убирая всю рефлексию при парсинге.
class MyData:
__slots__ = ('a', 'b')
def __reduce__(self):
return (self.__class__, (), {'a': self.a, 'b': self.b})

data = msgpack.packb(obj, default=lambda o: o.__reduce__(), use_bin_type=True)

Этот подход позволяет избежать стандартного вызова __dict__ и даёт прямой доступ к полям. Однако будьте осторожны: если структура данных меняется, __reduce__ может вернуть устаревший кортеж, и десериализация сломается.

Кастомные кодеки: контроль над упаковкой

В msgpack есть ExtType, в JSON - __json__ метод или кастомный encoder. Кастомный кодек позволяет упаковать объект в минимальный набор данных, например, числа в бинарные строки или сложные структуры в один вызов packb.
import msgpack

class FastEncoder:
ext_type = 42
def encode(self, obj):
if isinstance(obj, MyFastClass):
return msgpack.packb([obj.x, obj.y], use_bin_type=True)
raise TypeError

msgpack.packb(obj, default=FastEncoder().encode, strict_types=True)

На практике, под high-throughput RPC, комбинация __slots__ + __reduce__ + кастомный кодек даёт выигрыш в пропускной способности до 20-30% на мелких объектах. Но если объекты содержат много вложенных полей или тяжёлые структуры (например, строки длиннее 100 символов), кастомные кодеки могут стать медленнее из-за дополнительных вызовов packb. Торгуйте производительность и читаемость: для простых DTO - этот подход, для сложных графов - стандартная сериализация с оптимизацией в виде orjson.

Вывод: В high-throughput RPC микрооптимизации сериализации с __slots__, __reduce__ и кастомными кодеками дают реальный прирост производительности, но требуют строгого контроля над форматом данных и готовности к увеличению сложности поддержки.
More from @python_tesst
  1. Sep 28, 2026Post #3191
  2. Sep 27, 2026OpenAI метит в подписку за 500 баксов Что там в описании тарифа? Пока что от ChatGPT Pro о…
  3. Sep 27, 2026Post #3189
  4. Sep 27, 2026Свежая обложка The Economist подъехала Журналисты: да мы вообще не сгущаем краски Те же жу…
  5. Sep 27, 2026Ночная годнота: Docker выкатила первые официальные скиллы для ИИ-агентов, которые ковыряют…
  6. Sep 27, 2026Post #3186
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 →