perf: замеры без троттлинга CPU (решение человека)
Refs #202 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
419a20e950
commit
4836580c50
@ -150,3 +150,9 @@
|
|||||||
| 2026-10-25 | Только вертикальный скролл (ось y), роль `rf` | Бриф: «скролл при соавторе»; горизонтальная ось не зависит от потока входящих правок | Нет замера оси x при соавторе |
|
| 2026-10-25 | Только вертикальный скролл (ось y), роль `rf` | Бриф: «скролл при соавторе»; горизонтальная ось не зависит от потока входящих правок | Нет замера оси x при соавторе |
|
||||||
| 2026-10-25 | Вспомогательный `waitRows` продублирован в `scroll-coauthor.spec.ts`, а не вынесен в lib/ | Не трогать `scroll.spec.ts` Task 5; функция короткая | Дубли при правке |
|
| 2026-10-25 | Вспомогательный `waitRows` продублирован в `scroll-coauthor.spec.ts`, а не вынесен в lib/ | Не трогать `scroll.spec.ts` Task 5; функция короткая | Дубли при правке |
|
||||||
| 2026-10-25 | Фильтр свода по умолчанию мерится на `max(PERF_CPU_RATES)` (при умолчании `1`), имя теста `filter cpu<N>` | Троттлинг отключён по умолчанию, но `PERF_CPU_RATES=1,4,6` должен вести себя как прежде | Нет |
|
| 2026-10-25 | Фильтр свода по умолчанию мерится на `max(PERF_CPU_RATES)` (при умолчании `1`), имя теста `filter cpu<N>` | Троттлинг отключён по умолчанию, но `PERF_CPU_RATES=1,4,6` должен вести себя как прежде | Нет |
|
||||||
|
|
||||||
|
## Decisions made with the human
|
||||||
|
|
||||||
|
| Дата | Решение | Источник |
|
||||||
|
|---|---|---|
|
||||||
|
| 2026-10-25 | Замеры без троттлинга CPU: все сценарии по умолчанию на CPU 1×; код `throttle()` и env `PERF_CPU_RATES=1,4,6` оставлены для ручного включения; число повторов (3) не сокращено | Решение человека, передано координатором |
|
||||||
|
|||||||
@ -61,9 +61,9 @@ PERF_RUN_ID=t PERF_TARGETS='FORM_2/AHR/*' PERF_CPU_RATES=1 PERF_REPEATS=1 npx pl
|
|||||||
cd .. && .venv/bin/python -m perfkit.aggregate results/s1
|
cd .. && .venv/bin/python -m perfkit.aggregate results/s1
|
||||||
```
|
```
|
||||||
|
|
||||||
- Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1,4,6 x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`).
|
- Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1 (без троттлинга, решение человека) x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`).
|
||||||
- target: `FORM_x/<sheet>/<direction|null>`, `project/<report_type>/<project_id>`, `svod/<name>`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target).
|
- target: `FORM_x/<sheet>/<direction|null>`, `project/<report_type>/<project_id>`, `svod/<name>`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target).
|
||||||
- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (`1,4,6`), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл на CPU 6 порядка 40 мин).
|
- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (по умолчанию `1`; `1,4,6` включает троттлинг вручную), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл на CPU 6 порядка 40 мин).
|
||||||
- Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`.
|
- Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`.
|
||||||
- Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), Task 10 может исключать его из статистики. Trace первого повтора - в `perf/results/<run_id>/artifacts/` (30-70 МБ каждый, в git не попадают).
|
- Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), Task 10 может исключать его из статистики. Trace первого повтора - в `perf/results/<run_id>/artifacts/` (30-70 МБ каждый, в git не попадают).
|
||||||
- Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`.
|
- Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`.
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
* сопоставляется с target без суффикса оси и с полным (`.../@y`)
|
* сопоставляется с target без суффикса оси и с полным (`.../@y`)
|
||||||
* PERF_RUN_ID каталог прогона perf/results/<run_id>
|
* PERF_RUN_ID каталог прогона perf/results/<run_id>
|
||||||
* PERF_REPEATS число повторов вместо матричного (3 для rf/свод, 1 для admin-контроля)
|
* PERF_REPEATS число повторов вместо матричного (3 для rf/свод, 1 для admin-контроля)
|
||||||
* PERF_CPU_RATES '1,4,6' - список CPU throttling rate
|
* PERF_CPU_RATES '1' по умолчанию (без троттлинга, решение человека); '1,4,6' включает троттлинг вручную
|
||||||
* PERF_ROLES фильтр ролей через запятую (rf,admin,dfip)
|
* PERF_ROLES фильтр ролей через запятую (rf,admin,dfip)
|
||||||
* PERF_AXES 'y,x' - оси для rf (по умолчанию y,x)
|
* PERF_AXES 'y,x' - оси для rf (по умолчанию y,x)
|
||||||
* PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000)
|
* PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000)
|
||||||
@ -29,7 +29,8 @@ const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000);
|
|||||||
const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000);
|
const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000);
|
||||||
|
|
||||||
const envList = (n: string, d: string[]) => (process.env[n] ? process.env[n]!.split(',').map((s) => s.trim()).filter(Boolean) : d);
|
const envList = (n: string, d: string[]) => (process.env[n] ? process.env[n]!.split(',').map((s) => s.trim()).filter(Boolean) : d);
|
||||||
const CPU_RATES = envList('PERF_CPU_RATES', ['1', '4', '6']).map(Number);
|
const CPU_RATES = envList('PERF_CPU_RATES', ['1']).map(Number);
|
||||||
|
const FILTER_CPU = Math.max(...CPU_RATES); // замер смены фильтра: на самом тяжёлом из заданных CPU (по умолчанию 1)
|
||||||
const ROLES = envList('PERF_ROLES', ['rf', 'admin', 'dfip']);
|
const ROLES = envList('PERF_ROLES', ['rf', 'admin', 'dfip']);
|
||||||
const AXES = envList('PERF_AXES', ['y', 'x']) as Axis[];
|
const AXES = envList('PERF_AXES', ['y', 'x']) as Axis[];
|
||||||
const repeats = (dflt: number) => (process.env.PERF_REPEATS ? Number(process.env.PERF_REPEATS) : dflt);
|
const repeats = (dflt: number) => (process.env.PERF_REPEATS ? Number(process.env.PERF_REPEATS) : dflt);
|
||||||
@ -234,7 +235,7 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Таймаут теста: 45 мин по умолчанию, свод 2 (загрузка до 15 мин + скролл на CPU 6 ~40 мин) - 3 ч. */
|
/** Таймаут теста: 45 мин по умолчанию, свод 2 (загрузка до 15 мин + скролл на CPU 6 ~40 мин, если включён вручную) - 3 ч. */
|
||||||
const testTimeout = (t: Target) =>
|
const testTimeout = (t: Target) =>
|
||||||
t.kind === 'svod2'
|
t.kind === 'svod2'
|
||||||
? Number(process.env.PERF_TEST_TIMEOUT_SVOD2_MS ?? 3 * 3600_000)
|
? Number(process.env.PERF_TEST_TIMEOUT_SVOD2_MS ?? 3 * 3600_000)
|
||||||
@ -256,11 +257,11 @@ test.describe('scroll', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// смена фильтра - только своды, один раз на CPU 6
|
// смена фильтра - только своды, один раз на FILTER_CPU
|
||||||
if (t.kind !== 'sheet' && t.kind !== 'project' && CPU_RATES.includes(6)) {
|
if (t.kind !== 'sheet' && t.kind !== 'project') {
|
||||||
test(`${t.name} ${ra.role} filter cpu6`, async ({ browser }) => {
|
test(`${t.name} ${ra.role} filter cpu${FILTER_CPU}`, async ({ browser }) => {
|
||||||
test.setTimeout(testTimeout(t));
|
test.setTimeout(testTimeout(t));
|
||||||
await measure(browser, { t, role: ra.role, axis, cpu: 6, repeat: 0, filter: true });
|
await measure(browser, { t, role: ra.role, axis, cpu: FILTER_CPU, repeat: 0, filter: true });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user