perf: правки по финальному ревью — скрипты, данные, фильтр long tasks
- run-all.sh: копия run-all.status.json в report-data с относительными путями; пример control4x с отдельным тегом и предупреждением (I-3, M-8); очищены три закоммиченные копии статуса - lib/modal.ts: long tasks по пересечению окна (tasksInWindow), тест (M-7) - scale_compare.py: строки листов на момент скролла (до grow), пояснения (M-6) - hotspots_summary.py: оговорка о разбавлении «на шаг» (M-5) - netlog_sizes.py + report-data/20261026-s1/analysis/netlog-sizes.md (M-3) Refs #202 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5c1822026d
commit
5f4afc0926
@ -17,6 +17,12 @@ import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
STEP_NOTE = ("Шаги: hotspots.spec.ts всегда делает 40 шагов вперёд и 40 назад без проверки конца прокрутки. На коротких "
|
||||
"страницах (свод 1 MAIN — 17 шагов до конца, AHR_RENT — 31 строка) часть шагов ничего не прокручивает, и "
|
||||
"«на шаг» разбавлено: с main_thread_ms_per_step основного прогона (scroll.spec) не сравнивать; использовать доли, "
|
||||
"рендеры на коммит и состав топа.")
|
||||
|
||||
|
||||
def load(p: Path) -> list[dict]:
|
||||
return [json.loads(x) for x in p.read_text().splitlines()] if p.exists() else []
|
||||
|
||||
@ -70,12 +76,12 @@ def main(argv=None):
|
||||
(out / f"{a.name}.md").write_text("\n".join(md) + "\n")
|
||||
print("\n".join(md))
|
||||
return
|
||||
md += ["## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)", "",
|
||||
md += ["## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)", "", STEP_NOTE, "",
|
||||
"| target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс |", "|---|---|---|---|---|---|---|---|"]
|
||||
md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['commits_per_step']} | {r['renders_per_step']} | {r['td_renders_per_step']} | {r['react_self_ms']} | {r['main_thread_ms_per_step']} |" for r in res["react"]]
|
||||
for r in res["react"]:
|
||||
md.append(f"- {r['target']}: " + "; ".join(f"{c} {n}/{s} мс" for c, n, s in r["top"][:6]))
|
||||
md += ["", "## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md)", "",
|
||||
md += ["", "## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md)", "", STEP_NOTE, "",
|
||||
"| target | роль | шагов | main thread/шаг под профайлером, мс | профиль |", "|---|---|---|---|---|"]
|
||||
md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['main_thread_ms_per_step']} | `{', '.join(r['artifacts'])}` |" for r in res["cpu"]]
|
||||
md += ["", "## Фильтр свода: мутации DOM контейнера `.MuiTableContainer-root` за окно наблюдения после ввода «1»", "",
|
||||
|
||||
55
perf/analysis/netlog_sizes.py
Normal file
55
perf/analysis/netlog_sizes.py
Normal file
@ -0,0 +1,55 @@
|
||||
"""Размер ответов на проводе (сжатый, CDP) из сетевого лога сценариев - для report-data (network.jsonl в git не попадает).
|
||||
|
||||
cd perf && .venv/bin/python analysis/netlog_sizes.py results/20261026-s1 --out report-data/20261026-s1/analysis
|
||||
|
||||
По каждому шаблону пути данных (лист, отчёт проекта, своды) и шагу сценария: число ответов, медиана `body_size`
|
||||
(сжатый размер по CDP `request.sizes()`, gzip уровня 1 бэка) и медиана `duration_ms` в браузере.
|
||||
Распакованные размеры - в summary.md (bench, `bytes`) и `json_bytes_sheet` скролла. Вывод: <out>/netlog-sizes.md.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import statistics
|
||||
from collections import defaultdict
|
||||
from pathlib import Path
|
||||
|
||||
PATTERNS = [
|
||||
(re.compile(r"/api/v1/form/(\d+)/sheet/(\w+)(\?.*)?$"), lambda m: f"GET /form/{m.group(1)}/sheet/{m.group(2)}{m.group(3) or ''}"),
|
||||
(re.compile(r"/api/v1/projects/(\d+)/report/(\d+)/(\w+)$"), lambda m: f"GET /projects/{{id}}/report/{{year}}/{m.group(3)}"),
|
||||
(re.compile(r"/api/v1/svod/(\d)/(\w+)/(\d+)"), lambda m: f"GET /svod/{m.group(1)}/{m.group(2)}/{{year}}"),
|
||||
(re.compile(r"/api/v1/projects/plan-summary"), lambda m: "GET /projects/plan-summary"),
|
||||
]
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("run_dir")
|
||||
ap.add_argument("--out", required=True)
|
||||
a = ap.parse_args(argv)
|
||||
groups = defaultdict(lambda: {"size": [], "dur": []})
|
||||
for line in (Path(a.run_dir) / "network.jsonl").read_text().splitlines():
|
||||
r = json.loads(line)
|
||||
if r.get("method") != "GET" or r.get("status") != 200 or not r.get("body_size"):
|
||||
continue
|
||||
path = re.sub(r"^https?://[^/]+", "", r["url"])
|
||||
for rx, name in PATTERNS:
|
||||
m = rx.search(path)
|
||||
if m:
|
||||
g = groups[(name(m), r.get("scenario"), r.get("role"))]
|
||||
g["size"].append(r["body_size"])
|
||||
g["dur"].append(r.get("duration_ms") or 0)
|
||||
break
|
||||
md = [f"# Размер ответов на проводе (сжатый) по сетевому логу {Path(a.run_dir).name} (netlog_sizes.py)", "",
|
||||
"| запрос | сценарий | роль | ответов | медиана body_size, КБ | медиана duration_ms в браузере |", "|---|---|---|---|---|---|"]
|
||||
for (name, sc, role), g in sorted(groups.items(), key=lambda kv: -statistics.median(kv[1]["size"])):
|
||||
md.append(f"| {name} | {sc} | {role} | {len(g['size'])} | {statistics.median(g['size']) / 1024:.0f} | {statistics.median(g['dur']):.0f} |")
|
||||
out = Path(a.out)
|
||||
out.mkdir(parents=True, exist_ok=True)
|
||||
(out / "netlog-sizes.md").write_text("\n".join(md) + "\n")
|
||||
print("\n".join(md[:14]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -67,8 +67,17 @@ def main(argv=None):
|
||||
g1, g2 = groups(a.s1), groups(a.s2)
|
||||
m1 = json.loads((PERF / "report-data" / a.s1 / "manifest-s1.json").read_text())
|
||||
m2 = json.loads((PERF / "report-data" / a.s2 / "manifest-s2.json").read_text())
|
||||
rows1 = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in m1["sheets"] if s.get("owner", "rf") == "rf"}
|
||||
rows2 = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in m2["sheets"] if s.get("owner", "rf") == "rf"}
|
||||
def sheet_rows(man, run, scale):
|
||||
# скролл снят до grow: для выращенных листов берём число строк «до» из grow-sS.json (манифест - после grow)
|
||||
rows = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in man["sheets"] if s.get("owner", "rf") == "rf"}
|
||||
gp = PERF / "report-data" / run / f"grow-s{scale}.json"
|
||||
if gp.exists():
|
||||
for g in json.loads(gp.read_text()):
|
||||
rows[f"{g['sheet']}/null"] = g["before"]
|
||||
return rows
|
||||
|
||||
rows1 = sheet_rows(m1, a.s1, 1)
|
||||
rows2 = sheet_rows(m2, a.s2, 2)
|
||||
res = {"scroll": [], "modal": [], "api": []}
|
||||
for key, a1 in sorted(g1.items()):
|
||||
sc, target, role, cpu = key
|
||||
@ -112,6 +121,7 @@ def main(argv=None):
|
||||
|
||||
md = [f"# Масштаб 1 ({a.s1}) против масштаба 2 ({a.s2}, 1 повтор - оценка)", "",
|
||||
"## Скролл: main thread на шаг колеса 200 px, мс (медиана; s2 - один замер)", "",
|
||||
"Строк - на момент замера скролла (до grow; для AHR_UTILITY/AHR_SECURITY/FORM_4 CAP - значение «до» из grow-sS.json).", "",
|
||||
"| target | роль | строк s1 → s2 | мс/шаг s1 | мс/шаг s2 | × | main thread s1, мс | s2, мс | ответ s1 → s2, МБ |", "|---|---|---|---|---|---|---|---|---|"]
|
||||
for r in res["scroll"]:
|
||||
inc = " (s2 incomplete)" if r["inc_s2"] else ""
|
||||
@ -123,6 +133,7 @@ def main(argv=None):
|
||||
for r in res["modal"]:
|
||||
md.append(f"| {r['target']} | {r['role']} | {f(r['ms_s1'], 0)} | {f(r['ms_s2'], 0)} | {ratio(r['ms_s1'], r['ms_s2'])} | {f(r['mt_s1'], 0)} | {f(r['mt_s2'], 0)} |")
|
||||
md += ["", "## API (bench, медиана 20 повторов по каждому URL; размер - распакованный ответ)", "",
|
||||
"bench снят после grow: FORM_2/AHR - 2 092 строки на s1, AHR_UTILITY/SECURITY - 500, FORM_4/CAP - 300.", "",
|
||||
"| запрос | роль | s1, мс | s2, мс | × | s1, МБ | s2, МБ |", "|---|---|---|---|---|---|---|"]
|
||||
for r in res["api"]:
|
||||
md.append(f"| {r['endpoint']} | {r['role']} | {r['ms_s1']} | {r['ms_s2']} | {ratio(r['ms_s1'], r['ms_s2'])} | {r['mb_s1']} | {r['mb_s2']} |")
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
* - появление: MutationObserver (+ проверка на каждом кадре) ловит видимый элемент по `appear`
|
||||
* (по умолчанию `[role=dialog]`; у common/Modal и emotion-модалок приложения role нет, тогда css + text);
|
||||
* - конец: кадр после кадра с появившейся модалкой (двойной rAF = «модалка отрисована»);
|
||||
* - long tasks: PerformanceObserver 'longtask', засчитываются задачи, начавшиеся между pointerdown и концом;
|
||||
* - long tasks: PerformanceObserver 'longtask', засчитываются задачи, пересекающие окно [pointerdown, конец] (tasksInWindow:
|
||||
* задача клика начинается раньше, чем её обработчик pointerdown ставит t0);
|
||||
* - main_thread_ms: прирост CDP Performance.TaskDuration от клика до конца окна (все задачи main thread:
|
||||
* скрипт + стили + layout + paint-подготовка).
|
||||
* Нет модалки за timeoutMs (5 с) - ошибка с id модалки.
|
||||
@ -25,6 +26,11 @@ export interface OpenMetrics {
|
||||
|
||||
export const OPEN_TIMEOUT_MS = 5000;
|
||||
|
||||
/** Long tasks, пересекающие окно [t0, tEnd]: start <= tEnd и start + dur >= t0. */
|
||||
export function tasksInWindow<T extends { start: number; dur: number }>(tasks: T[], t0: number, tEnd: number): T[] {
|
||||
return tasks.filter((t) => t.start <= tEnd && t.start + t.dur >= t0);
|
||||
}
|
||||
|
||||
export async function measureOpen(page: Page, opener: () => Promise<unknown>, opts: OpenOpts): Promise<OpenMetrics> {
|
||||
const timeout = opts.timeoutMs ?? OPEN_TIMEOUT_MS;
|
||||
const appear: Required<Appear> = { css: opts.appear?.css ?? '[role=dialog]', text: opts.appear?.text ?? '' };
|
||||
@ -87,7 +93,7 @@ export async function measureOpen(page: Page, opener: () => Promise<unknown>, op
|
||||
if (res.timedOut || res.tEnd < 0) {
|
||||
throw new Error(`modal '${opts.id}' did not appear within ${timeout} ms (selector ${appear.css}${appear.text ? ` + text '${appear.text}'` : ''}, pointerdown ${res.t0 >= 0 ? 'seen' : 'not seen'})`);
|
||||
}
|
||||
const inWin = res.tasks.filter((t) => t.start >= res.t0 - 1 && t.start <= res.tEnd);
|
||||
const inWin = tasksInWindow(res.tasks, res.t0, res.tEnd);
|
||||
return {
|
||||
click_to_visible_ms: res.tEnd - res.t0,
|
||||
long_task_n: inWin.length,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import path from 'node:path';
|
||||
import { measureOpen } from '../lib/modal';
|
||||
import { measureOpen, tasksInWindow } from '../lib/modal';
|
||||
import { REACT_HOOK_SCRIPT, profileStart, profileStop } from '../lib/reactProfile';
|
||||
|
||||
const fx = (n: string) => 'file://' + path.resolve(__dirname, '../fixtures', n);
|
||||
@ -74,3 +74,15 @@ test('reactProfile: хук получает коммиты, топ-20 по displ
|
||||
expect(p.top[0].component).toBe('Row'); // сортировка по self_ms
|
||||
expect(p.top.length).toBeLessThanOrEqual(20);
|
||||
});
|
||||
|
||||
test('tasksInWindow: задача, начавшаяся до pointerdown и пересекающая окно, засчитывается (задача клика)', () => {
|
||||
const t0 = 100, tEnd = 300;
|
||||
const tasks = [
|
||||
{ start: 40, dur: 50 }, // закончилась до клика - нет
|
||||
{ start: 95, dur: 120 }, // задача клика: началась раньше t0 (обработчик pointerdown внутри неё) - да
|
||||
{ start: 150, dur: 60 }, // внутри окна - да
|
||||
{ start: 299, dur: 80 }, // началась до конца окна - да
|
||||
{ start: 310, dur: 60 }, // после окна - нет
|
||||
];
|
||||
expect(tasksInWindow(tasks, t0, tEnd).map((t) => t.start)).toEqual([95, 150, 299]);
|
||||
});
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
"start": "2026-10-26T12:26:46+0400",
|
||||
"end": "2026-10-26T12:59:48+0400",
|
||||
"duration_s": 1982,
|
||||
"cmd": "rc=0; ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_scroll PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_ROLES=rf,dfip PERF_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO' npx playwright test scenarios/scroll.spec.ts ) || rc=$?; ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_modals PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_PRIORITY=1,2 PERF_MODALS='sheet_select_vsp@big' npx playwright test scenarios/modals.spec.ts ) || rc=$?; exit $rc"
|
||||
"cmd": "rc=0; ( cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_scroll PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_ROLES=rf,dfip PERF_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO' npx playwright test scenarios/scroll.spec.ts ) || rc=$?; ( cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_modals PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_PRIORITY=1,2 PERF_MODALS='sheet_select_vsp@big' npx playwright test scenarios/modals.spec.ts ) || rc=$?; exit $rc"
|
||||
},
|
||||
"aggregate": {
|
||||
"status": "OK",
|
||||
@ -16,7 +16,7 @@
|
||||
"start": "2026-10-26T12:59:48+0400",
|
||||
"end": "2026-10-26T12:59:48+0400",
|
||||
"duration_s": 0,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-control-s1' && { [ ! -f 'results/20261026-control-s1/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-control-s1'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1' && for d in results/20261026-control-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-control-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-control-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/summary.json'"
|
||||
"cmd": "cd 'perf' && rm -f 'perf/report-data/20261026-control-s1/summary.json' && 'perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-control-s1' && { [ ! -f 'results/20261026-control-s1/modal.jsonl' ] || 'perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-control-s1'; } && mkdir -p 'perf/report-data/20261026-control-s1' && for d in results/20261026-control-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p 'perf/report-data/20261026-control-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json 'perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain 'perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-control-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-control-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" 'perf/report-data/20261026-control-s1/' || exit 1; fi; done && ls -R 'perf/report-data/20261026-control-s1' && test -f 'perf/report-data/20261026-control-s1/summary.json'"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)
|
||||
|
||||
Шаги: hotspots.spec.ts всегда делает 40 шагов вперёд и 40 назад без проверки конца прокрутки. На коротких страницах (свод 1 MAIN — 17 шагов до конца, AHR_RENT — 31 строка) часть шагов ничего не прокручивает, и «на шаг» разбавлено: с main_thread_ms_per_step основного прогона (scroll.spec) не сравнивать; использовать доли, рендеры на коммит и состав топа.
|
||||
|
||||
| target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| FORM_2/AHR/null:y | rf | 80 | 3.31 | 14808 | 1696 | 3708 | 76.5 |
|
||||
@ -21,6 +23,8 @@
|
||||
|
||||
## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md)
|
||||
|
||||
Шаги: hotspots.spec.ts всегда делает 40 шагов вперёд и 40 назад без проверки конца прокрутки. На коротких страницах (свод 1 MAIN — 17 шагов до конца, AHR_RENT — 31 строка) часть шагов ничего не прокручивает, и «на шаг» разбавлено: с main_thread_ms_per_step основного прогона (scroll.spec) не сравнивать; использовать доли, рендеры на коммит и состав топа.
|
||||
|
||||
| target | роль | шагов | main thread/шаг под профайлером, мс | профиль |
|
||||
|---|---|---|---|---|
|
||||
| FORM_2/AHR_RENT/null:y | rf | 80 | 7.7 | `artifacts/hot-FORM_2_AHR_RENT_null-y.cpuprofile` |
|
||||
|
||||
79
perf/report-data/20261026-s1/analysis/netlog-sizes.md
Normal file
79
perf/report-data/20261026-s1/analysis/netlog-sizes.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Размер ответов на проводе (сжатый) по сетевому логу 20261026-s1 (netlog_sizes.py)
|
||||
|
||||
| запрос | сценарий | роль | ответов | медиана body_size, КБ | медиана duration_ms в браузере |
|
||||
|---|---|---|---|---|---|
|
||||
| GET /svod/2/RF/{year} | scroll | admin | 4 | 3419 | 1910 |
|
||||
| GET /svod/2/RF/{year} | scroll | dfip | 4 | 3419 | 1828 |
|
||||
| GET /svod/2/GO/{year} | scroll | admin | 4 | 2347 | 1142 |
|
||||
| GET /svod/2/GO/{year} | scroll | dfip | 4 | 2347 | 1138 |
|
||||
| GET /form/7/sheet/AHR | memory | rf | 20 | 378 | 957 |
|
||||
| GET /form/7/sheet/AHR | modal | rf | 5 | 378 | 810 |
|
||||
| GET /form/7/sheet/AHR | modal_renders | rf | 1 | 378 | 797 |
|
||||
| GET /form/1/sheet/AHR?direction=Support | scroll | admin | 1 | 329 | 4445 |
|
||||
| GET /form/7/sheet/AHR | scroll_coauthor | rf | 6 | 323 | 431 |
|
||||
| GET /form/7/sheet/AHR | scroll | rf | 6 | 321 | 705 |
|
||||
| GET /form/7/sheet/AHR | scroll | admin | 1 | 321 | 720 |
|
||||
| GET /form/1/sheet/AHR?direction=Development | scroll | admin | 1 | 319 | 366 |
|
||||
| GET /form/4/sheet/AHR | scroll | admin | 1 | 316 | 361 |
|
||||
| GET /form/1/sheet/CAP?direction=Development | scroll | admin | 1 | 265 | 187 |
|
||||
| GET /form/1/sheet/CAP?direction=Support | scroll | admin | 1 | 259 | 214 |
|
||||
| GET /form/4/sheet/CAP | scroll | admin | 1 | 247 | 223 |
|
||||
| GET /form/7/sheet/CAP | scroll | rf | 6 | 243 | 225 |
|
||||
| GET /form/7/sheet/CAP | scroll | admin | 1 | 242 | 220 |
|
||||
| GET /form/1/sheet/OPER | scroll | admin | 1 | 193 | 412 |
|
||||
| GET /form/7/sheet/OPER | scroll | rf | 6 | 189 | 184 |
|
||||
| GET /form/7/sheet/OPER | scroll | admin | 1 | 189 | 161 |
|
||||
| GET /form/4/sheet/OPER | scroll | admin | 1 | 187 | 186 |
|
||||
| GET /form/13/sheet/STRUCTURE | scroll | rf | 6 | 182 | 234 |
|
||||
| GET /form/13/sheet/STRUCTURE | scroll_coauthor | rf | 6 | 182 | 211 |
|
||||
| GET /form/13/sheet/STRUCTURE | memory | rf | 20 | 182 | 274 |
|
||||
| GET /form/13/sheet/STRUCTURE | scroll | admin | 1 | 182 | 269 |
|
||||
| GET /projects/{id}/report/{year}/LIMIT | scroll | rf | 36 | 161 | 387 |
|
||||
| GET /projects/{id}/report/{year}/CURRENT_EXPENSES | scroll | rf | 36 | 159 | 392 |
|
||||
| GET /projects/plan-summary | scroll | admin | 4 | 108 | 388 |
|
||||
| GET /projects/plan-summary | scroll | dfip | 4 | 108 | 381 |
|
||||
| GET /form/13/sheet/CAP | modal | rf | 15 | 73 | 1775 |
|
||||
| GET /form/13/sheet/CAP | modal_renders | rf | 3 | 73 | 1680 |
|
||||
| GET /form/13/sheet/AHR | scroll | rf | 6 | 48 | 709 |
|
||||
| GET /form/13/sheet/AHR | modal | rf | 15 | 48 | 679 |
|
||||
| GET /form/13/sheet/AHR | modal_renders | rf | 3 | 48 | 648 |
|
||||
| GET /form/13/sheet/AHR | scroll | admin | 1 | 48 | 713 |
|
||||
| GET /form/13/sheet/OPER | scroll | rf | 6 | 47 | 692 |
|
||||
| GET /form/13/sheet/OPER | scroll | admin | 1 | 47 | 737 |
|
||||
| GET /form/13/sheet/CAP | scroll | admin | 1 | 45 | 652 |
|
||||
| GET /form/13/sheet/CAP | scroll | rf | 6 | 45 | 701 |
|
||||
| GET /svod/1/MAIN/{year} | scroll | admin | 20 | 44 | 332 |
|
||||
| GET /svod/1/MAIN/{year} | scroll | dfip | 20 | 44 | 336 |
|
||||
| GET /svod/1/FORM_1/{year} | scroll | admin | 4 | 37 | 113 |
|
||||
| GET /svod/1/FORM_1/{year} | scroll | dfip | 4 | 37 | 103 |
|
||||
| GET /form/1/sheet/SMETA | scroll | admin | 1 | 34 | 498 |
|
||||
| GET /svod/1/FORM_2/{year} | scroll | admin | 4 | 22 | 118 |
|
||||
| GET /svod/1/FORM_2/{year} | scroll | dfip | 4 | 22 | 119 |
|
||||
| GET /form/7/sheet/SMETA | scroll | rf | 6 | 21 | 106 |
|
||||
| GET /form/7/sheet/SMETA | scroll | admin | 1 | 21 | 106 |
|
||||
| GET /form/4/sheet/SMETA | scroll | admin | 1 | 21 | 130 |
|
||||
| GET /svod/1/FORM_4/{year} | scroll | admin | 4 | 19 | 46 |
|
||||
| GET /svod/1/FORM_4/{year} | scroll | dfip | 4 | 19 | 48 |
|
||||
| GET /form/7/sheet/AHR_UTILITY | modal | rf | 5 | 17 | 33 |
|
||||
| GET /form/7/sheet/AHR_UTILITY | modal_renders | rf | 1 | 17 | 35 |
|
||||
| GET /svod/1/FORM_3/{year} | scroll | admin | 4 | 13 | 78 |
|
||||
| GET /svod/1/FORM_3/{year} | scroll | dfip | 4 | 13 | 83 |
|
||||
| GET /form/13/sheet/SMETA | scroll | rf | 6 | 12 | 66 |
|
||||
| GET /form/13/sheet/SMETA | scroll | admin | 1 | 12 | 74 |
|
||||
| GET /form/7/sheet/AHR_SECURITY | scroll | rf | 6 | 2 | 15 |
|
||||
| GET /form/7/sheet/AHR_LIMIT | scroll | rf | 6 | 2 | 17 |
|
||||
| GET /form/7/sheet/AHR_SECURITY | scroll | admin | 1 | 2 | 16 |
|
||||
| GET /form/4/sheet/AHR_LIMIT | scroll | admin | 1 | 2 | 23 |
|
||||
| GET /form/7/sheet/AHR_LIMIT | scroll | admin | 1 | 2 | 12 |
|
||||
| GET /form/7/sheet/AHR_RENT | scroll | rf | 6 | 2 | 15 |
|
||||
| GET /form/7/sheet/AHR_RENT | modal | rf | 10 | 2 | 15 |
|
||||
| GET /form/7/sheet/AHR_RENT | modal_renders | rf | 2 | 2 | 15 |
|
||||
| GET /form/7/sheet/AHR_UTILITY | scroll | rf | 6 | 2 | 15 |
|
||||
| GET /form/7/sheet/AHR_RENT | scroll | admin | 1 | 2 | 14 |
|
||||
| GET /form/7/sheet/AHR_UTILITY | scroll | admin | 1 | 2 | 13 |
|
||||
| GET /form/4/sheet/AHR_SECURITY | scroll | admin | 1 | 0 | 15 |
|
||||
| GET /form/7/sheet/OTCH9F | scroll | rf | 6 | 0 | 16 |
|
||||
| GET /form/4/sheet/AHR_UTILITY | scroll | admin | 1 | 0 | 11 |
|
||||
| GET /form/4/sheet/AHR_RENT | scroll | admin | 1 | 0 | 14 |
|
||||
| GET /form/4/sheet/OTCH9F | scroll | admin | 1 | 0 | 14 |
|
||||
| GET /form/7/sheet/OTCH9F | scroll | admin | 1 | 0 | 18 |
|
||||
@ -8,7 +8,7 @@
|
||||
"start": "2026-10-26T03:15:25+0400",
|
||||
"end": "2026-10-26T03:15:31+0400",
|
||||
"duration_s": 6,
|
||||
"cmd": "'/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' reset"
|
||||
"cmd": "'perf/stand.sh' reset"
|
||||
},
|
||||
"gen": {
|
||||
"status": "OK",
|
||||
@ -16,7 +16,7 @@
|
||||
"start": "2026-10-26T03:15:31+0400",
|
||||
"end": "2026-10-26T03:26:14+0400",
|
||||
"duration_s": 643,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.run --scale 1"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.run --scale 1"
|
||||
},
|
||||
"verify": {
|
||||
"status": "OK",
|
||||
@ -24,7 +24,7 @@
|
||||
"start": "2026-10-26T03:26:14+0400",
|
||||
"end": "2026-10-26T03:26:23+0400",
|
||||
"duration_s": 8,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.verify --scale 1"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.verify --scale 1"
|
||||
},
|
||||
"stand": {
|
||||
"status": "OK",
|
||||
@ -32,7 +32,7 @@
|
||||
"start": "2026-10-26T03:26:23+0400",
|
||||
"end": "2026-10-26T03:26:24+0400",
|
||||
"duration_s": 1,
|
||||
"cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' api) && ([ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' smoke"
|
||||
"cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || 'perf/stand.sh' api) && ([ -f 'perf/.build/prod/index.html' ] || 'perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || 'perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - 'perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && 'perf/stand.sh' smoke"
|
||||
},
|
||||
"preflight": {
|
||||
"status": "OK",
|
||||
@ -40,7 +40,7 @@
|
||||
"start": "2026-10-26T03:26:24+0400",
|
||||
"end": "2026-10-26T03:26:26+0400",
|
||||
"duration_s": 2,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts scenarios/scroll-coauthor.spec.ts scenarios/memory.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done"
|
||||
"cmd": "cd 'perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts scenarios/scroll-coauthor.spec.ts scenarios/memory.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done"
|
||||
},
|
||||
"scroll": {
|
||||
"status": "OK",
|
||||
@ -48,7 +48,7 @@
|
||||
"start": "2026-10-26T03:26:26+0400",
|
||||
"end": "2026-10-26T06:29:23+0400",
|
||||
"duration_s": 10977,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=scroll npx playwright test scenarios/scroll.spec.ts"
|
||||
"cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=scroll npx playwright test scenarios/scroll.spec.ts"
|
||||
},
|
||||
"coauthor": {
|
||||
"status": "FAIL",
|
||||
@ -56,7 +56,7 @@
|
||||
"start": "2026-10-26T06:29:23+0400",
|
||||
"end": "2026-10-26T06:34:34+0400",
|
||||
"duration_s": 311,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=coauthor PERF_COAUTHOR_RATES=1,5 npx playwright test scenarios/scroll-coauthor.spec.ts"
|
||||
"cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=coauthor PERF_COAUTHOR_RATES=1,5 npx playwright test scenarios/scroll-coauthor.spec.ts"
|
||||
},
|
||||
"grow": {
|
||||
"status": "OK",
|
||||
@ -64,7 +64,7 @@
|
||||
"start": "2026-10-26T06:34:34+0400",
|
||||
"end": "2026-10-26T06:38:12+0400",
|
||||
"duration_s": 218,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.grow --scale 1"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.grow --scale 1"
|
||||
},
|
||||
"modals": {
|
||||
"status": "OK",
|
||||
@ -72,7 +72,7 @@
|
||||
"start": "2026-10-26T06:38:12+0400",
|
||||
"end": "2026-10-26T06:47:01+0400",
|
||||
"duration_s": 529,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts"
|
||||
"cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts"
|
||||
},
|
||||
"modals_profiling": {
|
||||
"status": "OK",
|
||||
@ -80,7 +80,7 @@
|
||||
"start": "2026-10-26T06:47:01+0400",
|
||||
"end": "2026-10-26T06:48:38+0400",
|
||||
"duration_s": 97,
|
||||
"cmd": "rc=0; '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-profiling && ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8081 PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1 npx playwright test scenarios/modals.spec.ts ) || rc=$?; if [ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid' ]; then pkill -P $(cat '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid') 2>/dev/null; kill $(cat '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid') 2>/dev/null; rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid'; fi; exit $rc"
|
||||
"cmd": "rc=0; 'perf/stand.sh' web-profiling && ( cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8081 PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1 npx playwright test scenarios/modals.spec.ts ) || rc=$?; if [ -f 'perf/.run/web-profiling.pid' ]; then pkill -P $(cat 'perf/.run/web-profiling.pid') 2>/dev/null; kill $(cat 'perf/.run/web-profiling.pid') 2>/dev/null; rm -f 'perf/.run/web-profiling.pid'; fi; exit $rc"
|
||||
},
|
||||
"memory": {
|
||||
"status": "OK",
|
||||
@ -88,7 +88,7 @@
|
||||
"start": "2026-10-26T06:48:38+0400",
|
||||
"end": "2026-10-26T07:44:37+0400",
|
||||
"duration_s": 3359,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=memory npx playwright test scenarios/memory.spec.ts"
|
||||
"cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=memory npx playwright test scenarios/memory.spec.ts"
|
||||
},
|
||||
"memtrend": {
|
||||
"status": "OK",
|
||||
@ -96,7 +96,7 @@
|
||||
"start": "2026-10-26T07:44:37+0400",
|
||||
"end": "2026-10-26T07:44:37+0400",
|
||||
"duration_s": 0,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.memtrend 'results/20261026-s1' | tee 'results/20261026-s1/memtrend.txt'"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.memtrend 'results/20261026-s1' | tee 'results/20261026-s1/memtrend.txt'"
|
||||
},
|
||||
"bench": {
|
||||
"status": "OK",
|
||||
@ -104,7 +104,7 @@
|
||||
"start": "2026-10-26T07:44:37+0400",
|
||||
"end": "2026-10-26T07:54:02+0400",
|
||||
"duration_s": 564,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s1' --repeats 20 --scale 1"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s1' --repeats 20 --scale 1"
|
||||
},
|
||||
"aggregate": {
|
||||
"status": "OK",
|
||||
@ -112,7 +112,7 @@
|
||||
"start": "2026-10-26T07:54:02+0400",
|
||||
"end": "2026-10-26T07:54:02+0400",
|
||||
"duration_s": 0,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s1' && { [ ! -f 'results/20261026-s1/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s1'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1' && for d in results/20261026-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/summary.json'"
|
||||
"cmd": "cd 'perf' && rm -f 'perf/report-data/20261026-s1/summary.json' && 'perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s1' && { [ ! -f 'results/20261026-s1/modal.jsonl' ] || 'perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s1'; } && mkdir -p 'perf/report-data/20261026-s1' && for d in results/20261026-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p 'perf/report-data/20261026-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json 'perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain 'perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" 'perf/report-data/20261026-s1/' || exit 1; fi; done && ls -R 'perf/report-data/20261026-s1' && test -f 'perf/report-data/20261026-s1/summary.json'"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -93,8 +93,8 @@
|
||||
{
|
||||
"target": "FORM_2/AHR_SECURITY/null@x",
|
||||
"role": "rf",
|
||||
"rows_s1": 500,
|
||||
"rows_s2": 500,
|
||||
"rows_s1": 31,
|
||||
"rows_s2": 61,
|
||||
"mt_per_step_s1": 85.5549375,
|
||||
"mt_per_step_s2": 83.62412499999999,
|
||||
"mt_s1": 2737.758,
|
||||
@ -108,8 +108,8 @@
|
||||
{
|
||||
"target": "FORM_2/AHR_SECURITY/null@y",
|
||||
"role": "rf",
|
||||
"rows_s1": 500,
|
||||
"rows_s2": 500,
|
||||
"rows_s1": 31,
|
||||
"rows_s2": 61,
|
||||
"mt_per_step_s1": 76.4081875,
|
||||
"mt_per_step_s2": 77.01785,
|
||||
"mt_s1": 611.2655,
|
||||
@ -123,8 +123,8 @@
|
||||
{
|
||||
"target": "FORM_2/AHR_UTILITY/null@x",
|
||||
"role": "rf",
|
||||
"rows_s1": 500,
|
||||
"rows_s2": 500,
|
||||
"rows_s1": 31,
|
||||
"rows_s2": 61,
|
||||
"mt_per_step_s1": 86.60009375,
|
||||
"mt_per_step_s2": 82.18025,
|
||||
"mt_s1": 2771.203,
|
||||
@ -138,8 +138,8 @@
|
||||
{
|
||||
"target": "FORM_2/AHR_UTILITY/null@y",
|
||||
"role": "rf",
|
||||
"rows_s1": 500,
|
||||
"rows_s2": 500,
|
||||
"rows_s1": 31,
|
||||
"rows_s2": 61,
|
||||
"mt_per_step_s1": 77.100875,
|
||||
"mt_per_step_s2": 79.7505,
|
||||
"mt_s1": 616.807,
|
||||
@ -303,8 +303,8 @@
|
||||
{
|
||||
"target": "FORM_4/CAP/null@x",
|
||||
"role": "rf",
|
||||
"rows_s1": 300,
|
||||
"rows_s2": 300,
|
||||
"rows_s1": 110,
|
||||
"rows_s2": 210,
|
||||
"mt_per_step_s1": 88.53567530487805,
|
||||
"mt_per_step_s2": 87.65557926829268,
|
||||
"mt_s1": 29039.7015,
|
||||
@ -318,8 +318,8 @@
|
||||
{
|
||||
"target": "FORM_4/CAP/null@y",
|
||||
"role": "rf",
|
||||
"rows_s1": 300,
|
||||
"rows_s2": 300,
|
||||
"rows_s1": 110,
|
||||
"rows_s2": 210,
|
||||
"mt_per_step_s1": 93.31751315789475,
|
||||
"mt_per_step_s2": 89.75829487179487,
|
||||
"mt_s1": 3546.0655000000006,
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
## Скролл: main thread на шаг колеса 200 px, мс (медиана; s2 - один замер)
|
||||
|
||||
Строк - на момент замера скролла (до grow; для AHR_UTILITY/AHR_SECURITY/FORM_4 CAP - значение «до» из grow-sS.json).
|
||||
|
||||
| target | роль | строк s1 → s2 | мс/шаг s1 | мс/шаг s2 | × | main thread s1, мс | s2, мс | ответ s1 → s2, МБ |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| FORM_2/AHR/null@x | rf | 1154 → 1744 | 78.7 | 78.3 | 1.00 | 26899 | 26786 | 4.29 → 6.50 |
|
||||
@ -10,10 +12,10 @@
|
||||
| FORM_2/AHR_LIMIT/null@y | rf | 27 → 27 | 71.1 | 71.7 | 1.01 | 284 | 287 | 0.01 → 0.01 |
|
||||
| FORM_2/AHR_RENT/null@x | rf | 31 → 61 | 91.2 | 83.5 | 0.92 | 3102 | 2840 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_RENT/null@y | rf | 31 → 61 | 77.4 | 78.9 | 1.02 | 619 | 1578 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_SECURITY/null@x | rf | 500 → 500 | 85.6 | 83.6 | 0.98 | 2738 | 2676 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_SECURITY/null@y | rf | 500 → 500 | 76.4 | 77.0 | 1.01 | 611 | 1540 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_UTILITY/null@x | rf | 500 → 500 | 86.6 | 82.2 | 0.95 | 2771 | 2630 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_UTILITY/null@y | rf | 500 → 500 | 77.1 | 79.8 | 1.03 | 617 | 1595 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_SECURITY/null@x | rf | 31 → 61 | 85.6 | 83.6 | 0.98 | 2738 | 2676 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_SECURITY/null@y | rf | 31 → 61 | 76.4 | 77.0 | 1.01 | 611 | 1540 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_UTILITY/null@x | rf | 31 → 61 | 86.6 | 82.2 | 0.95 | 2771 | 2630 | 0.02 → 0.03 |
|
||||
| FORM_2/AHR_UTILITY/null@y | rf | 31 → 61 | 77.1 | 79.8 | 1.03 | 617 | 1595 | 0.02 → 0.03 |
|
||||
| FORM_2/CAP/null@x | rf | 708 → 1208 | 78.8 | 80.4 | 1.02 | 27000 | 27483 | 2.65 → 4.51 |
|
||||
| FORM_2/CAP/null@y | rf | 708 → 1208 | 85.4 | 87.2 | 1.02 | 23740 | 41698 | 2.65 → 4.51 |
|
||||
| FORM_2/OPER/null@x | rf | 547 → 1047 | 80.1 | 80.7 | 1.01 | 27395 | 27600 | 2.03 → 3.88 |
|
||||
@ -24,8 +26,8 @@
|
||||
| FORM_2/SMETA/null@y | rf | 134 → 134 | 84.9 | 85.0 | 1.00 | 4075 | 4080 | 0.10 → 0.10 |
|
||||
| FORM_4/AHR/null@x | rf | 110 → 210 | 90.6 | 87.3 | 0.96 | 29727 | 28632 | 0.44 → 0.84 |
|
||||
| FORM_4/AHR/null@y | rf | 110 → 210 | 90.2 | 89.5 | 0.99 | 3426 | 6984 | 0.44 → 0.84 |
|
||||
| FORM_4/CAP/null@x | rf | 300 → 300 | 88.5 | 87.7 | 0.99 | 29040 | 28751 | 0.44 → 0.83 |
|
||||
| FORM_4/CAP/null@y | rf | 300 → 300 | 93.3 | 89.8 | 0.96 | 3546 | 7001 | 0.44 → 0.83 |
|
||||
| FORM_4/CAP/null@x | rf | 110 → 210 | 88.5 | 87.7 | 0.99 | 29040 | 28751 | 0.44 → 0.83 |
|
||||
| FORM_4/CAP/null@y | rf | 110 → 210 | 93.3 | 89.8 | 0.96 | 3546 | 7001 | 0.44 → 0.83 |
|
||||
| FORM_4/OPER/null@x | rf | 110 → 210 | 89.0 | 88.3 | 0.99 | 29383 | 29129 | 0.44 → 0.84 |
|
||||
| FORM_4/OPER/null@y | rf | 110 → 210 | 92.1 | 90.2 | 0.98 | 3498 | 7036 | 0.44 → 0.84 |
|
||||
| FORM_4/SMETA/null@x | rf | 109 → 109 | 61.8 | 62.8 | 1.02 | 1235 | 1255 | 0.08 → 0.08 |
|
||||
@ -121,6 +123,8 @@
|
||||
|
||||
## API (bench, медиана 20 повторов по каждому URL; размер - распакованный ответ)
|
||||
|
||||
bench снят после grow: FORM_2/AHR - 2 092 строки на s1, AHR_UTILITY/SECURITY - 500, FORM_4/CAP - 300.
|
||||
|
||||
| запрос | роль | s1, мс | s2, мс | × | s1, МБ | s2, МБ |
|
||||
|---|---|---|---|---|---|---|
|
||||
| GET свод 2 RF | dfip | 1805.5 | 7319.2 | 4.05 | 52.69 | 195.08 |
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
"start": "2026-10-26T07:54:02+0400",
|
||||
"end": "2026-10-26T07:54:08+0400",
|
||||
"duration_s": 6,
|
||||
"cmd": "'/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' reset"
|
||||
"cmd": "'perf/stand.sh' reset"
|
||||
},
|
||||
"gen": {
|
||||
"status": "OK",
|
||||
@ -16,7 +16,7 @@
|
||||
"start": "2026-10-26T07:54:08+0400",
|
||||
"end": "2026-10-26T08:49:46+0400",
|
||||
"duration_s": 3338,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.run --scale 2"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.run --scale 2"
|
||||
},
|
||||
"verify": {
|
||||
"status": "OK",
|
||||
@ -24,7 +24,7 @@
|
||||
"start": "2026-10-26T08:49:46+0400",
|
||||
"end": "2026-10-26T08:50:06+0400",
|
||||
"duration_s": 20,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.verify --scale 2"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.verify --scale 2"
|
||||
},
|
||||
"stand": {
|
||||
"status": "OK",
|
||||
@ -32,7 +32,7 @@
|
||||
"start": "2026-10-26T08:50:06+0400",
|
||||
"end": "2026-10-26T08:50:07+0400",
|
||||
"duration_s": 1,
|
||||
"cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' api) && ([ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' smoke"
|
||||
"cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || 'perf/stand.sh' api) && ([ -f 'perf/.build/prod/index.html' ] || 'perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || 'perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - 'perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && 'perf/stand.sh' smoke"
|
||||
},
|
||||
"preflight": {
|
||||
"status": "OK",
|
||||
@ -40,7 +40,7 @@
|
||||
"start": "2026-10-26T08:50:07+0400",
|
||||
"end": "2026-10-26T08:50:08+0400",
|
||||
"duration_s": 1,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done"
|
||||
"cmd": "cd 'perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done"
|
||||
},
|
||||
"scroll": {
|
||||
"status": "OK",
|
||||
@ -48,7 +48,7 @@
|
||||
"start": "2026-10-26T08:50:08+0400",
|
||||
"end": "2026-10-26T11:19:59+0400",
|
||||
"duration_s": 8991,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=scroll PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts"
|
||||
"cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=scroll PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts"
|
||||
},
|
||||
"coauthor": {
|
||||
"status": "SKIP",
|
||||
@ -64,7 +64,7 @@
|
||||
"start": "2026-10-26T11:19:59+0400",
|
||||
"end": "2026-10-26T11:22:15+0400",
|
||||
"duration_s": 136,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.grow --scale 2"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.grow --scale 2"
|
||||
},
|
||||
"modals": {
|
||||
"status": "OK",
|
||||
@ -72,7 +72,7 @@
|
||||
"start": "2026-10-26T11:22:15+0400",
|
||||
"end": "2026-10-26T11:31:24+0400",
|
||||
"duration_s": 549,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts"
|
||||
"cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts"
|
||||
},
|
||||
"modals_profiling": {
|
||||
"status": "SKIP",
|
||||
@ -104,7 +104,7 @@
|
||||
"start": "2026-10-26T11:31:25+0400",
|
||||
"end": "2026-10-26T11:47:44+0400",
|
||||
"duration_s": 979,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s2' --repeats 20 --scale 2"
|
||||
"cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s2' --repeats 20 --scale 2"
|
||||
},
|
||||
"aggregate": {
|
||||
"status": "OK",
|
||||
@ -112,7 +112,7 @@
|
||||
"start": "2026-10-26T11:47:44+0400",
|
||||
"end": "2026-10-26T11:47:44+0400",
|
||||
"duration_s": 0,
|
||||
"cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s2' && { [ ! -f 'results/20261026-s2/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s2'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2' && for d in results/20261026-s2/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s2/memtrend.txt results/manifest-s2.json results/gen-stats-s2.json results/grow-s2.json results/20261026-s2/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/summary.json'"
|
||||
"cmd": "cd 'perf' && rm -f 'perf/report-data/20261026-s2/summary.json' && 'perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s2' && { [ ! -f 'results/20261026-s2/modal.jsonl' ] || 'perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s2'; } && mkdir -p 'perf/report-data/20261026-s2' && for d in results/20261026-s2/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p 'perf/report-data/20261026-s2/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json 'perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain 'perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s2/memtrend.txt results/manifest-s2.json results/gen-stats-s2.json results/grow-s2.json results/20261026-s2/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" 'perf/report-data/20261026-s2/' || exit 1; fi; done && ls -R 'perf/report-data/20261026-s2' && test -f 'perf/report-data/20261026-s2/summary.json'"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,10 @@
|
||||
# perf/run-all.sh # всё: масштаб 1, затем 2
|
||||
# PERF_DRY_RUN=1 perf/run-all.sh # план: шаги, команды, оценка длительности; ничего не запускает
|
||||
# PERF_SCALES=2 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=modals,bench,aggregate perf/run-all.sh # возобновить
|
||||
# PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_STEPS=control4x,aggregate \
|
||||
# PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,modal:sheet_select_vsp' perf/run-all.sh # контроль CPU 4x
|
||||
# PERF_SCALES=1 PERF_RUN_TAG=20261026-control PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggregate \
|
||||
# PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO,modal:sheet_select_vsp@big' perf/run-all.sh # контроль CPU 4x
|
||||
# ВНИМАНИЕ: control4x с тегом основного прогона (PERF_RUN_TAG=20261026) допишет в results/20261026-s1 и пересоберёт
|
||||
# report-data/20261026-s1 (summary, копии манифеста/gen-stats/grow) - для контроля нужен отдельный тег (design.md).
|
||||
#
|
||||
# Переменные:
|
||||
# PERF_SCALES масштабы по порядку (по умолчанию "1 2")
|
||||
@ -31,6 +33,7 @@
|
||||
set -uo pipefail
|
||||
|
||||
PERF="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_ROOT="$(dirname "$PERF")" # копия run-all.status.json в report-data - с путями относительно корня репозитория
|
||||
E2E="$PERF/e2e"
|
||||
PY="${PERF_PY:-$PERF/.venv/bin/python}" # python для perfkit (подмена - только тесты run-all)
|
||||
STATUS_PY="$PERF/.venv/bin/python"
|
||||
@ -149,8 +152,9 @@ step_cmd() {
|
||||
"&& mkdir -p '$out' && for d in results/$RID/sql/*/; do if [ -d \"\$d\" ]; then t=\$(basename \"\$d\");" \
|
||||
"mkdir -p '$out/sql/'\$t || exit 1; if [ -f \"\$d\"sql_top.json ]; then cp \"\$d\"sql_top.json '$out/sql/'\$t/ || exit 1; fi;" \
|
||||
"if [ -d \"\$d\"explain ]; then cp -R \"\$d\"explain '$out/sql/'\$t/ || exit 1; fi; fi; done" \
|
||||
"&& for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json results/$RID/run-all.status.json;" \
|
||||
"&& for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json;" \
|
||||
"do if [ -f \"\$f\" ]; then cp \"\$f\" '$out/' || exit 1; fi; done" \
|
||||
"&& { [ ! -f 'results/$RID/run-all.status.json' ] || sed 's#$REPO_ROOT/##g' 'results/$RID/run-all.status.json' > '$out/run-all.status.json'; }" \
|
||||
"&& ls -R '$out' && test -f '$out/summary.json'" ;;
|
||||
esac
|
||||
}
|
||||
@ -238,7 +242,7 @@ for SCALE in $SCALES; do
|
||||
fi
|
||||
done
|
||||
# итоговый статус - и в report-data (если aggregate уже создал каталог)
|
||||
[ -d "$PERF/report-data/$RID" ] && cp "$STATUS" "$PERF/report-data/$RID/"
|
||||
[ -d "$PERF/report-data/$RID" ] && sed "s#$REPO_ROOT/##g" "$STATUS" > "$PERF/report-data/$RID/run-all.status.json"
|
||||
log "=== масштаб $SCALE готов: $(jq -r '[.steps|to_entries[]|"\(.key)=\(.value.status)"]|join(" ")' "$STATUS" 2>/dev/null)"
|
||||
done
|
||||
if [ "$DRY" = 1 ]; then
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user