Производительность: числовые требования и чем их замерять #30

Closed
opened 2026-08-01 15:46:08 +03:00 by ddmitry · 2 comments
Owner

Part of #26.

Вопрос

Какие числовые требования производительности зафиксировать: время пересборки эталонного мира и параметры живого потока с ускорением ×60? Чем и как замерять?

Рамка уже решена (разделы 9 и 11 мастер-спеки): рабочее решение — Python с батчевой генерацией и распараллеливанием по модельным дням; компилируемый язык — только если замеры покажут, что Python приемлемой скорости не даёт. Здесь фиксируются числа, а не слова «быстро» (критерий приёмки #14).

Хвост из решения «Модель мира» (#27): зафиксировать числом ускорение живого дня (×60 — рабочая гипотеза мастер-спеки) и длину эталонного снимка (рабочая гипотеза владельца — около недели).

Part of #26. ## Вопрос Какие числовые требования производительности зафиксировать: время пересборки эталонного мира и параметры живого потока с ускорением ×60? Чем и как замерять? Рамка уже решена (разделы 9 и 11 мастер-спеки): рабочее решение — Python с батчевой генерацией и распараллеливанием по модельным дням; компилируемый язык — только если замеры покажут, что Python приемлемой скорости не даёт. Здесь фиксируются числа, а не слова «быстро» (критерий приёмки #14). Хвост из решения «Модель мира» (#27): зафиксировать числом ускорение живого дня (×60 — рабочая гипотеза мастер-спеки) и длину эталонного снимка (рабочая гипотеза владельца — около недели).
ddmitry added the wayfinder:grilling label 2026-08-01 15:46:45 +03:00
Author
Owner

Хвост из решения «Архитектура» (#29): при фиксации длины эталонного снимка числами проверить оговорку — заливка снимка при старте идёт через Kafka пакетным режимом и должна укладываться в минуты; если выходит в десятки минут, возвращаемся к прямой загрузке как осознанному backfill-компромиссу.

Хвост из решения «Архитектура» (#29): при фиксации длины эталонного снимка числами проверить оговорку — заливка снимка при старте идёт через Kafka пакетным режимом и должна укладываться в минуты; если выходит в десятки минут, возвращаемся к прямой загрузке как осознанному backfill-компромиссу.
ddmitry self-assigned this 2026-08-01 17:27:32 +03:00
Author
Owner

Резолюция (сессия 2026-08-01, владелец подтвердил):

  1. Объём модельного дня — ~50 тыс. событий в среднем (суточные волны: пики до ~2× среднего, будни/выходные; ≈8–12 тыс. сессий, 6–8 тыс. посетителей — правдоподобный средний магазин).
  2. Эталонный снимок — 14 дней: две полные календарные недели (D0 — понедельник). Самая короткая длина, при которой есть и замороженная зона за окном K=7, и дышащая, и две волны недельной сезонности. Удлинение до месяца — дешёвый ход (пересборка манифеста), если захочется.
  3. В git — только манифест, снимок не хранится. Снимок генерируется при make up и при проверках: артефакт — кэш чистой функции (#28), кэш в git не хранят. Манифест несёт паспорт мира, счётчики и хеши по дням; «пустой git diff» и «пересгенерируй день N — сравни хеш» переезжают на него без потерь, боль «каждый PR генератора тащит гигантский дифф» исчезает, каждый make up — живая демонстрация детерминизма. Честная потеря — страховка от платформенного бага (менти с расходящимися байтами упрётся в красный чек манифеста); смягчение — CI гоняет генерацию на amd64 и arm64. Это расхождение с разделом 8 мастер-спеки — правится тем же коммитом, что спека генератора.
  4. Живой день — ×60 по умолчанию (модельные сутки за 24 реальные минуты: суточная волна разворачивается на глазах, темп ~35–100 соб/с). Число — значение по умолчанию в спеке, переопределяется флагом проигрывателя: ускорение — свойство транспорта, вне обещания воспроизводимости (#28). Константой мира не делается.
  5. Бюджеты — двухъярусная схема (урок ADR 0004: пороги впритык к расчёту на разном железе — путь к ритуальному удалению проверки). Ориентиры на референсной машине — в спеку, без автоматики: генерация дня ~секунды; пересборка эталонного мира (генерация 14 дней + манифест, без транспорта) — до минуты; заливка снимка (Kafka → матвью → ODS, при make up) — минуты; лаг живого дня — секунды. Автоматический порог один: полный день (50 тыс.) генерируется ≤ 30 с — расчёт ~1 с, машинный разброс ×2–5, ловится деградация на 1–2 порядка (Faker в горячем цикле, случайная квадратичность). Реализация: pytest-тест с маркером perf и таймаутом-обрубанием на пороге; обязателен в CI, исключён из быстрой локальной петли, зовётся отдельной целью при правках горячего цикла. Остальное — наблюдаемость без порогов: make up/smoke печатают тайминги (генерация и доставка отдельно), проигрыватель логирует лаг.
  6. Прототип-замер из тумана карты не нужен: числа назначены с запасом порядок и больше от планки #31, а планка подтверждена локальной проверкой на машине стенда. Первый замер настоящего кода — порог этапа 2. Пункт тумана рассеивается без тикета.
  7. Оговорка из «Архитектуры» (#29) проверена: заливка 14 × 50 тыс. ≈ 700 тыс. событий — расчётно минута-две, «минуты, не десятки минут» соблюдается с запасом. Снимок при старте остаётся через Kafka.

Отклонено с доводами:

  • Четыре жёстких CI-ворот на все бюджеты: машинный разброс против порогов впритык — повторение истории с памятью (ADR 0004); порог оставлен один, грубый, между «×5 шума» и «×100 беды».
  • Снимок в git (статус-кво раздела 8): основание из v1 — медленный генератор — съедено детерминизмом #28 и скоростью #31; остаётся только раздутый репозиторий.
  • Снимок вложением релиза Gitea: страховка без раздутия, но лишняя машинерия и вторая правда.
  • Снимок 7 дней: ни одного замороженного дня, сезонность без сравнения. 30 дней: нового урока не даёт — отложено как дешёвое удлинение.
  • ×120 / ×1440: волна смазывается в перемотку / это пакет с анимацией, живой режим теряет смысл.

Хвосты: в #32 — правка мастер-спеки тем же коммитом: раздел 8 (манифест вместо артефакта в git) и раздел 11 (числа вместо «зафиксировать требования»). Этапу 5 — живой день со стороны хранилища есть просто ETL-даг на расписании (~раз в 24 минуты), генератор не дорабатывается. Этапу 7 — пересборка = манифест, не артефакт; CI-генерация на amd64 и arm64. Будущим лабам — перезаливка дня X пакетным режимом проигрывателя = готовая демка идемпотентности.

Резолюция (сессия 2026-08-01, владелец подтвердил): 1. **Объём модельного дня — ~50 тыс. событий в среднем** (суточные волны: пики до ~2× среднего, будни/выходные; ≈8–12 тыс. сессий, 6–8 тыс. посетителей — правдоподобный средний магазин). 2. **Эталонный снимок — 14 дней**: две полные календарные недели (D0 — понедельник). Самая короткая длина, при которой есть и замороженная зона за окном K=7, и дышащая, и две волны недельной сезонности. Удлинение до месяца — дешёвый ход (пересборка манифеста), если захочется. 3. **В git — только манифест, снимок не хранится.** Снимок генерируется при `make up` и при проверках: артефакт — кэш чистой функции (#28), кэш в git не хранят. Манифест несёт паспорт мира, счётчики и хеши по дням; «пустой git diff» и «пересгенерируй день N — сравни хеш» переезжают на него без потерь, боль «каждый PR генератора тащит гигантский дифф» исчезает, каждый `make up` — живая демонстрация детерминизма. Честная потеря — страховка от платформенного бага (менти с расходящимися байтами упрётся в красный чек манифеста); смягчение — CI гоняет генерацию на amd64 и arm64. Это расхождение с разделом 8 мастер-спеки — правится тем же коммитом, что спека генератора. 4. **Живой день — ×60 по умолчанию** (модельные сутки за 24 реальные минуты: суточная волна разворачивается на глазах, темп ~35–100 соб/с). Число — значение по умолчанию в спеке, переопределяется флагом проигрывателя: ускорение — свойство транспорта, вне обещания воспроизводимости (#28). Константой мира не делается. 5. **Бюджеты — двухъярусная схема** (урок ADR 0004: пороги впритык к расчёту на разном железе — путь к ритуальному удалению проверки). Ориентиры на референсной машине — в спеку, без автоматики: генерация дня ~секунды; пересборка эталонного мира (генерация 14 дней + манифест, без транспорта) — до минуты; заливка снимка (Kafka → матвью → ODS, при `make up`) — минуты; лаг живого дня — секунды. **Автоматический порог один: полный день (50 тыс.) генерируется ≤ 30 с** — расчёт ~1 с, машинный разброс ×2–5, ловится деградация на 1–2 порядка (Faker в горячем цикле, случайная квадратичность). Реализация: pytest-тест с маркером `perf` и таймаутом-обрубанием на пороге; обязателен в CI, исключён из быстрой локальной петли, зовётся отдельной целью при правках горячего цикла. Остальное — наблюдаемость без порогов: `make up`/smoke печатают тайминги (генерация и доставка отдельно), проигрыватель логирует лаг. 6. **Прототип-замер из тумана карты не нужен**: числа назначены с запасом порядок и больше от планки #31, а планка подтверждена локальной проверкой на машине стенда. Первый замер настоящего кода — порог этапа 2. Пункт тумана рассеивается без тикета. 7. **Оговорка из «Архитектуры» (#29) проверена**: заливка 14 × 50 тыс. ≈ 700 тыс. событий — расчётно минута-две, «минуты, не десятки минут» соблюдается с запасом. Снимок при старте остаётся через Kafka. **Отклонено с доводами:** - *Четыре жёстких CI-ворот на все бюджеты*: машинный разброс против порогов впритык — повторение истории с памятью (ADR 0004); порог оставлен один, грубый, между «×5 шума» и «×100 беды». - *Снимок в git (статус-кво раздела 8)*: основание из v1 — медленный генератор — съедено детерминизмом #28 и скоростью #31; остаётся только раздутый репозиторий. - *Снимок вложением релиза Gitea*: страховка без раздутия, но лишняя машинерия и вторая правда. - *Снимок 7 дней*: ни одного замороженного дня, сезонность без сравнения. *30 дней*: нового урока не даёт — отложено как дешёвое удлинение. - *×120 / ×1440*: волна смазывается в перемотку / это пакет с анимацией, живой режим теряет смысл. **Хвосты:** в #32 — правка мастер-спеки тем же коммитом: раздел 8 (манифест вместо артефакта в git) и раздел 11 (числа вместо «зафиксировать требования»). Этапу 5 — живой день со стороны хранилища есть просто ETL-даг на расписании (~раз в 24 минуты), генератор не дорабатывается. Этапу 7 — пересборка = манифест, не артефакт; CI-генерация на amd64 и arm64. Будущим лабам — перезаливка дня X пакетным режимом проигрывателя = готовая демка идемпотентности.
Sign in to join this conversation.