# Perf Этапы 6 и 7 — разбор и решение (НЕ реализованы, обоснованно) Этапы 6/7 из плана при проверке по факту кода оказались нацелены **не на горячие места**. Реализовывать их сейчас = добавить сложность/риск ради нулевого или недоказанного выигрыша. ## Этап 6 — per-hit кэш mastery/базового урона: ПРОПУЩЕН (ценность ≈ ноль) Предпосылка плана: «убрать дорогой per-hit `pc_checkskill`». По факту в uAthena `pc_checkskill` (src/map/pc.c:4013) — это **O(1)**: ```c if(sd->status.skill[skill_id].id == skill_id) return sd->status.skill[skill_id].lv; return 0; ``` Прямой индекс массива + сравнение. `battle_addmastery`/`battle_calc_weapon_attack` дёргают его ~10 раз за удар, плюс мелкие циклы по `add_damage_class_count` (обычно 0–несколько) и `status_get_*`, возвращающие кэш-указатели. **Горячего per-hit пути нет.** Кэш mastery в `status_data` дал бы неизмеримый выигрыш, но добавил бы поверхность инвалидации (пересчёт при смене скиллов/экипа). Не делаем. ## Этап 7 — delta-пересчёт `status_calc_pc`: ОТЛОЖЕН (нужен профиль; высокий риск) `status_calc_pc(sd, first)` (src/map/status.c:1621) — большой (~816 строк) **полный** пересчёт производных статов (нет SCB-флагов; `first` — лишь признак первого расчёта). НО: - Вызывается **по событиям**, не per-tick: pc.c (24), atcommand/charcommand (админ), pet.c (3), status.c (1), script.c (1). **Ни одного вызова в таймере/тике** (проверено). - Churn статус-эффектов (баффы/дебаффы в WoE) идёт **не** через него, а через `status_calc_bl(bl, flag)` с **SCB-делтой** — это уже эффективный частичный пересчёт. - Полный `status_calc_pc` бьёт только на экип/левелап/логин/рефайн — относительно редко. Переписать 816-строчную функцию на delta — крупное изменение с высоким риском **тихих багов статов** в только что портированной item-bonus подсистеме (тестировщику такое трудно поймать). Сам план помечал этап 7 как «делать ПОСЛЕДНИМ и только если профиль тестировщиков оправдает». **Критерий вернуться к этапу 7:** профиль `UA_PERF=1` на боевом кластере (300 онлайн, WoE) показывает `status_calc_pc` заметной долей CPU. Если нет — не трогать. ## Где на самом деле остались выигрыши (для следующего раунда, по профилю) Все известные **код-сайд** per-tick хотспоты уже устранены за проект: natural-heal → `map_foreachpc`; mob AI → livemob/mobgrid; lazy-AI таймер; skill_unit AoE → live-индекс + presence-gate + LoS-кэш (этап 2); recv parse-shortlist (этап 3); broadcast block-skip (этап 4a); send-буфер пул (этап 5a). Проверка таймеров игрового цикла: остальные периодические таймеры лёгкие или ограничены числом онлайн-сущностей (guild/party XY, pet/merc AI, OnClock) — не хотспоты. Следующий **крупный** рычаг — сетевое ядро (доминирующий расход под нагрузкой по прошлому профилю): - **`SO_SNDBUF`** (`socket_sndbuf_size`, готов, деф. 0): тестировщикам попробовать 131072–262144. - **io_uring** для отправки — реально срезает syscall/qdisc-оверхед; крупная отдельная переделка, делать только если профиль 300-онлайн подтвердит, что сеть-ядро доминирует. - **Ops:** многоочередь virtio-net + RPS/XPS. Любой из них стоит начинать **с baseline-профиля тестировщиков** (этапы 2/3/4a/5a уже в бинаре, все флаги ON) — чтобы оптимизировать измеренное, а не предполагаемое.