perf: README — порядок разбора и отчёта, web-sourcemap, hotspots
Refs #202 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
af0975100b
commit
eb5e40e9ef
@ -9,7 +9,7 @@ perf/stand.sh all # up, migrate, bootstrap, web-build, api, web, smoke
|
||||
perf/stand.sh down # остановить бэк, фронт и Postgres
|
||||
```
|
||||
|
||||
Подкоманды: `up | migrate | bootstrap | api | web-build | web | smoke | reset | down | all`.
|
||||
Подкоманды: `up | migrate | bootstrap | api | web-build | web | web-profiling | web-sourcemap | smoke | reset | down | all` (`web-profiling` — профилирующая сборка на :8081, `web-sourcemap` — prod-сборка с source maps на :8082 для CPU-профилей, раздел «Анализ и отчёт»).
|
||||
`reset` — чистая БД: останавливает бэк, сносит volume Postgres, поднимает заново (`up`, `migrate`, `bootstrap`, `api`); фронт не трогает.
|
||||
|
||||
- Postgres 16 (`pg_stat_statements`) на `localhost:55432`, `perf/perf/perf`.
|
||||
@ -198,3 +198,66 @@ PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggre
|
||||
- `PERF_CONTROL_TARGETS`: `modal:<id>` — модалка, `coauthor:<glob>` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор (без trace); записи идут в тот же run_id (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`.
|
||||
- Контроль выполняется после `grow`: для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP цифры 4x несопоставимы со скроллом 1x.
|
||||
|
||||
|
||||
## Анализ и отчёт: `perf/analysis/`, `perf/REPORT.md`
|
||||
|
||||
Отчёт — `perf/REPORT.md` (каждая цифра ссылается на файл в `perf/report-data/<run_id>/`). Порядок воспроизведения:
|
||||
|
||||
1. Полный прогон: `PERF_S2_REPEATS=1 perf/run-all.sh` -> `results/<дата>-s1|s2`, `report-data/<дата>-s1|s2` (summary, sql, memtrend...).
|
||||
2. После прогона в БД масштаб 2. Для ручного разбора и контроля CPU 4x восстановить масштаб 1 (~20 мин):
|
||||
`perf/stand.sh reset && cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 && .venv/bin/python -m perfkit.gen.verify --scale 1 && .venv/bin/python -m perfkit.gen.grow --scale 1`.
|
||||
Состав данных эквивалентен замеренному (тот же план), но не побитово; `results/manifest-s1.json` перезаписывается (копия прогона - в `report-data/<run_id>/`).
|
||||
3. Разбор сырых данных прогона (без живой БД):
|
||||
|
||||
```
|
||||
cd perf
|
||||
.venv/bin/python analysis/timeline_breakdown.py results/20261026-s1 --out report-data/20261026-s1/analysis # trace -> scripting/rendering/gc на шаг, точки входа JS
|
||||
.venv/bin/python analysis/heapdiff.py results/20261026-s1/artifacts/memory-cycle10.heapsnapshot \
|
||||
results/20261026-s1/artifacts/memory-cycle20.heapsnapshot --base results/20261026-s1/artifacts/memory-cycle00.heapsnapshot \
|
||||
--out report-data/20261026-s1/analysis # рост классов, retainers новых объектов
|
||||
.venv/bin/python analysis/memory_cycles.py results/20261026-s1 --out report-data/20261026-s1/analysis # таблица циклов памяти (cycle_s)
|
||||
.venv/bin/python analysis/scale_compare.py --s1 20261026-s1 --s2 20261026-s2 --out report-data/20261026-s2/analysis # масштаб 1 против 2
|
||||
```
|
||||
|
||||
4. Разбор на живой БД масштаба 1 (шаг 2):
|
||||
|
||||
```
|
||||
.venv/bin/python analysis/explain_manual.py --scale 1 --out report-data/20261026-s1/explain-manual # EXPLAIN вложенных запросов, jit/work_mem, pg_stat_statements
|
||||
.venv/bin/python analysis/api_split.py --scale 1 --out report-data/20261026-s1/analysis # полное время API против X-DB-Time-Ms
|
||||
```
|
||||
|
||||
`explain_manual.py` берёт тексты запросов из последних версий функций в `api/alembic/versions/sql/` по диапазонам строк
|
||||
с якорями (при изменении функции скрипт падает с сообщением), подставляет параметры литералами, выполняет EXPLAIN
|
||||
(ANALYZE, BUFFERS) в транзакции с ROLLBACK и делает `pg_stat_statements_reset()` - не запускать параллельно с замерами.
|
||||
|
||||
5. Горячие точки фронта (`perf/e2e/scenarios/hotspots.spec.ts`, в run-all не входит): CPU-профиль на prod-сборке с source maps
|
||||
и счётчики рендеров React на профилирующей сборке.
|
||||
|
||||
```
|
||||
perf/stand.sh web-sourcemap # prod-сборка с source maps (PERF_SOURCEMAP=1, perf/.build/prod-sourcemap) на :8082; код = :8080 с точностью до хешей чанков
|
||||
perf/stand.sh web-profiling # профилирующая сборка на :8081
|
||||
cd perf/e2e
|
||||
PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_HOT_MODE=cpu PERF_WEB=http://localhost:8082 \
|
||||
PERF_HOT_TARGETS='FORM_2/AHR/null:y,FORM_2/AHR/null:x,FORM_4/STRUCTURE/null:y,project/LIMIT/1/2026:y,svod/svod1_MAIN:y,svod/projects_summaries:y,svod/svod2_GO:y,svod/svod2_GO:filter,svod/svod2_RF:filter,svod/svod1_MAIN:filter' \
|
||||
npx playwright test scenarios/hotspots.spec.ts
|
||||
PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_HOT_MODE=react PERF_WEB=http://localhost:8081 \
|
||||
PERF_HOT_TARGETS='FORM_2/AHR/null:y,FORM_2/AHR/null:x,FORM_4/STRUCTURE/null:y,project/LIMIT/1/2026:y,svod/svod1_MAIN:y,svod/projects_summaries:y,svod/svod2_GO:y,svod/svod2_GO:filter' \
|
||||
npx playwright test scenarios/hotspots.spec.ts
|
||||
PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_HOT_MODE=cpu PERF_WEB=http://localhost:8080 PERF_HOT_CYCLES=15 \
|
||||
PERF_HOT_SHEET2=FORM_4/STRUCTURE/null PERF_HOT_TARGETS='FORM_2/AHR/null:cssgrowth' npx playwright test scenarios/hotspots.spec.ts
|
||||
PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_WEB=http://localhost:8081 PERF_PROFILING=1 PERF_PRIORITY=2 PERF_REPEATS=1 \
|
||||
PERF_MODALS='dict_vsp_*' npx playwright test scenarios/modals.spec.ts # рендеры модалок справочника ВСП
|
||||
cd ..
|
||||
.venv/bin/python analysis/cpuprofile_top.py results/20261026-hot --maps .build/prod-sourcemap --out report-data/20261026-s1/analysis
|
||||
.venv/bin/python analysis/hotspots_summary.py results/20261026-hot --out report-data/20261026-s1/analysis
|
||||
```
|
||||
|
||||
- `hotspots.spec.ts`: `PERF_HOT_TARGETS` - `<target>:<action>` (target как в scroll.spec без оси; action `y`, `x`, `filter`,
|
||||
`cssgrowth`), `PERF_HOT_MODE` (`cpu` - `artifacts/hot-*.cpuprofile`; `react` - рендеры по компонентам), `PERF_HOT_STEPS` (40 шагов
|
||||
вперёд и столько же назад), `PERF_HOT_FILTER_MS` (30 с наблюдения за мутациями DOM после ввода фильтра), `PERF_HOT_CYCLES`,
|
||||
`PERF_HOT_SHEET2`, `PERF_HOT_ROLE`. Записи - `hotspot_cpu.jsonl` / `hotspot_react.jsonl`; под профайлером абсолютное время выше,
|
||||
сравнивать доли.
|
||||
- `cpuprofile_top.py` декодирует source maps сам (VLQ, без зависимостей): self time по функциям и пакетам, «ближайший кадр
|
||||
`web/src`» в стеке каждого сэмпла (кто в коде приложения вызвал работу библиотек) и inclusive time функций `web/src`.
|
||||
- Имена выходных файлов без «trace» (`timeline-breakdown.*`): шаблон `.gitignore` `perf/**/*trace*.json` исключает трассы.
|
||||
- py-spy (`perf/requirements.txt`) на macOS требует root - не запускается без sudo; вместо него `analysis/api_split.py`.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user