Skip to content

perf(point_update): обрабатывать только активных, без скана character_list (#3414)#3417

Open
bylins wants to merge 2 commits into
masterfrom
feat/point-update-active-list-3414
Open

perf(point_update): обрабатывать только активных, без скана character_list (#3414)#3417
bylins wants to merge 2 commits into
masterfrom
feat/point-update-active-list-3414

Conversation

@bylins
Copy link
Copy Markdown
Owner

@bylins bylins commented Jun 6, 2026

Пример решения по #3414 — на валидацию @kvirund (draft, не для мёржа как есть).

Шаг в сторону #3180: без новых глобалов — активный набор живёт в самом реестре Characters.

Суть

point_update больше не сканирует весь character_list (десятки тысяч мобов мира ради пропуска неактивных — это и давало спайк ~111 мс). Вместо этого:

  • Characters::m_active — мобы, которых mobile_activity уже признал активными. Врезка строго O(1) (mark_active(ch) сразу после ++processed_mobs), без новых проходов в и так перегруженном мобакте. Сбрасывается каждый point_update (clear_active).
  • Characters::m_players — все игроки в игре. Наполняется в push_front (единственная точка входа PC в character_list), чистится в remove. По игрокам идём всегда → поведение PC не меняется, включая link-dead (их не теряем, в отличие от обхода descriptor_list).
  • point_update берёт снимок active()+players() в вектор, clear_active(), затем идёт по снимку. Висячие указатели исключены чисткой в Characters::remove + проверкой purged() на каждой итерации.

Открытые вопросы для валидации

  1. Смена семантики мобов: регенерируются только активные мобы, а не все в used-зоне. Для простаивающих безвредно (полный HP, ресет восстановит), но это сознательное изменение — ок?
  2. m_players как владелец PC vs альтернативы (descriptor_list) — устраивает ли такой выбор владельца в духе refactor: уменьшить зависимость от глобального состояния #3180?
  3. Тот же приём напрашивается и для самого mobile_activity (отдельная задача — мобакт перегружен).

Проверка

Инкрементальная сборка (ninja -C build) — без ошибок. Замер до/после удобно снять профайлером частей из #3412 (там просмотрено должно резко упасть).

Связано: #3414, #3180.

🤖 Generated with Claude Code

@bylins bylins requested a review from kvirund June 6, 2026 10:43
@bylins bylins force-pushed the feat/point-update-active-list-3414 branch from 5ee1165 to 5f645de Compare June 6, 2026 10:51
Comment thread src/gameplay/core/game_limits.cpp Outdated
Comment on lines +1537 to +1547
// #3414: вместо скана всего character_list -- только активные мобы
// (их помечает mobile_activity) и все игроки в игре. Снимок указателей,
// чтобы отложенные extract не ломали обход set'ов между итерациями.
std::vector<CharData *> to_update;
to_update.reserve(character_list.active().size() + character_list.players().size());
for (auto *m : character_list.active()) {
to_update.push_back(m);
}
for (auto *p : character_list.players()) {
to_update.push_back(p);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как насчёт отдельной функции? Просто чтобы читалось проще.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Согласен, сделал — вынес в Characters::active_and_players(), теперь в point_update один вызов вместо двух циклов. Заодно логика «активные+игроки» уехала к владельцу реестра (в духе #3180). Коммит 9650138.

@bylins bylins force-pushed the feat/point-update-active-list-3414 branch from 5f645de to a1eb18e Compare June 6, 2026 12:15
bylins and others added 2 commits June 6, 2026 16:32
…_list (#3414)

Пример решения по #3414 (шаг к #3180, без новых глобалов).

point_update раньше каждый MUD-час шёл по всему character_list (все мобы
мира, десятки тысяч), пропуская не-активных фильтром in_used_zone -- сам
скан и давал спайк ~111 мс.

Теперь активный набор ведётся в самом реестре Characters (а не новый
глобал):
- m_active -- мобы, помеченные mobile_activity (одна O(1)-вставка в точке
  ++processed_mobs), сбрасывается каждый point_update;
- m_players -- все игроки в игре (наполняется в push_front, чистится в
  remove), чтобы поведение PC не изменилось (в т.ч. link-dead).

point_update берёт снимок active()+players() и идёт по нему; висячие
указатели исключены чисткой в Characters::remove + проверкой purged().

Семантика мобов меняется: регенерируются только активные мобы (для
простаивающих безвредно). На валидацию.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…players()

По ревью @kvirund: два цикла active()+players() в point_update заменены на
один вызов метода реестра. Читается проще и логика "активные+игроки" уезжает
к своему владельцу Characters (в духе #3180).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@bylins bylins force-pushed the feat/point-update-active-list-3414 branch from 9650138 to e92a263 Compare June 6, 2026 14:35
@bylins bylins marked this pull request as ready for review June 6, 2026 19:13
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.

2 participants