Skip to content

perf(mob_stat): бинарный формат + фоновая запись вместо XML (#3296)#3299

Open
bylins wants to merge 1 commit into
masterfrom
perf/mob-stat-binary-async-save-3296
Open

perf(mob_stat): бинарный формат + фоновая запись вместо XML (#3296)#3299
bylins wants to merge 1 commit into
masterfrom
perf/mob-stat-binary-async-save-3296

Conversation

@bylins
Copy link
Copy Markdown
Owner

@bylins bylins commented May 20, 2026

Summary

mob_stat::Save строил pugixml-DOM (тысячи нод + атрибутов) и синхронно писал XML. На проде файл ~3.8 МБ → спайк ~47 мс в одном heartbeat-пульсе (бюджет 40 мс), раз в kSavePeriod минут. Load при бутe тоже парсил весь XML.

Файл машинный, руками не правится (твоя идея) — XML тут только тормозил и запись, и чтение. Перевёл на бинарь:

  • Save: прямая сериализация в std::string на главном потоке (быстро, без пер-нодовых аллокаций), запись на диск — в фоновом utils::ThreadPool(1) через .tmp + rename (атомарно). heartbeat-пульс больше не держит дисковую запись.
  • Load: читает mob_stat.bin (magic + version + записи). Если .bin нет — разовая миграция со старого mob_stat_new.xml; следующий Save уже пишет бинарь. Старый XML после миграции остаётся на диске (безвреден), при желании уберём.
  • Валидация статов (диапазон месяца, окно истории, накопление count_stats/kill_stats) вынесена в общий ApplyParsedStat для обоих путей.

Формат: нативный порядок байт (файл не шарится между архитектурами), fixed-массив kills[kMaxGroupSize+1] на запись стата. magic 'MSTB' отличает бинарь от любого мусора.

Test plan

  • meson -Dyaml=builtin собирается
  • meson test -C build_yaml2 — зелёные
  • прод: первый бут после деплоя мигрирует с XML, show stats показывает те же числа
  • следующий Save создаёт mob_stat.bin, рестарт грузит из него
  • в профайле heartbeat шаг "Mob stats saving" падает до долей мс

По #3296.

🤖 Generated with Claude Code

mob_stat::Save строил pugixml-DOM (тысячи нод + атрибутов) и синхронно
писал XML. На проде файл ~3.8 МБ -> спайк ~47 мс в одном heartbeat-
пульсе (бюджет пульса 40 мс) раз в kSavePeriod минут. Load при бутe
тоже парсил весь XML через pugixml.

Файл машинный, руками не правится -- XML тут только тормозил. Перевод
на бинарь:

- Save: прямая сериализация в std::string на главном потоке (быстро,
  без пер-нодовых аллокаций), запись на диск -- в фоновом
  utils::ThreadPool через .tmp + rename. heartbeat-пульс больше не
  держит дисковую запись.
- Load: читает mob_stat.bin (magic + version + records). Если .bin нет
  -- разовая миграция со старого mob_stat_new.xml; следующий Save уже
  пишет бинарь.
- Валидация статов (диапазон месяца, окно истории, count_stats/
  kill_stats) вынесена в общий ApplyParsedStat для обоих путей.

Формат: нативный порядок байт (файл не шарится между архитектурами),
fixed-массив kills[kMaxGroupSize+1] на запись стата.

По #3296.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant