awesome-everything EN
↑ Обратно к восхождению

Производительность

Что делает путь горячим: симптом против причины

Суть Широкий фрейм во flame graph показывает, где накапливается время, но не почему. Один и тот же leaf может скрывать пять разных узких мест — каждое требует своей правки.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 12 min

Профиль готов. Один фрейм во flame graph широкий. Двое инженеров хотят сменить шаблонизатор. Третий спрашивает: «Широкий от чего? CPU-работа, аллокации, lock contention или syscall?» Только один из четырёх вариантов имеет «сменить шаблонизатор» как правильный fix.

Что такое hot path

Hot path — это цепочка вызовов, в которой программа проводит большую часть времени. Профиль показывает её как стек широких фреймов, поднимающихся от leaf’а к top-level entry. Leaf называет функцию; вопрос — почему эта функция дорогая.

Современное железо превращает ту же «1 секунду CPU» в очень разные проблемы в зависимости от того, что CPU реально делал: исполнял инструкции, ждал памяти, ждал лока, ждал возврата syscall. Диагноз решает, какое семейство правок применимо.

Применение неверной правки к верному hotspot’у — вторая по частоте трата в performance-работе, после оптимизации не того hotspot’а вообще (разобрана в unit’е profile-first).

Метафора приёмной

Приёмная у врача переполнена. Это говорит, что в приёмной много людей — не говорит, почему. Пациенты ждут врача, лабораторию, бумаги, парковку? У каждого варианта своя правка: больше врачей, более быстрая лаборатория, меньше форм, больше мест для парковки.

Широкий фрейм во flame graph — то же самое: приёмная полная; спроси, чего люди ждут внутри.

Широкий фрейм показываетЧто это реально означаетКуда смотреть дальше
Высокий self-time в пользовательской функцииФункция делает настоящую CPU-работуИзучи алгоритм или data layout
Широкие GC-фреймы рядом с leaf’омCaller много аллоцируетПереключись на allocation profile
Широкий в wall-clock, узкий в CPUФункция ждёт — лок или syscallСними off-CPU или mutex profile
Фрейм интерпретатора там, где должен быть JITJIT деоптимизировался — откат к baselineСтабилизируй формы объектов / типы

Bea и Sven: один фрейм, два прочтения

Антон · Браузер находит processOrder на 35% CPU и хочет переписать цикл. Дима · Origin-сервер смотрит внимательнее: большая часть этих 35% — в runtime.scanobject (GC), вызываемом изнутри цикла. Цикл много аллоцирует. Правка — sync.Pool, не новый алгоритм.

Flame graph показал симптом. Причина — на уровень глубже.

Сценарий: regex на каждый запрос

Search-эндпоинт показывает regex.test как широкий leaf. Двое инженеров хотят сменить regex-движок. Третий смотрит на parent: regex компилируется на каждом запросе, потому что паттерн строится из шаблонной строки. Правка — компилировать один раз на старте. Leaf указал на правильную область; баг был в паттерне caller’а, не в самом leaf’е.

Почему это работает

Leaf — это лампочка на dashboard’е: «здесь что-то не так». Правка может быть внутри функции (переписать алгоритм), в caller’е (не вызывать так часто), в callee (реальная цена уровнем ниже) или в окружающем контексте (меньше аллоцировать, реже брать лок, меньше syscall’ов). Сеньоры читают весь район, не только leaf.

Викторина

Flame graph показывает широкий leaf-фрейм. Что спросить ПЕРВЫМ?

Викторина

Почему «широкий фрейм = bottleneck» — неполное прочтение flame graph?

Расставь шаги по порядку

Расставь шаги сеньорной атаки на hot path по порядку:

  1. 1 Открой профиль и найди самый широкий leaf-фрейм по self-time
  2. 2 Прочти parent chain — leaf вызывается из одного пути или из многих?
  3. 3 Классифицируй работу: CPU-инструкции, аллокации, cache miss, lock wait, syscall или JIT deopt
  4. 4 Сформулируй одну гипотезу правки, соответствующей классификации
  5. 5 Применить ТОЛЬКО это изменение изолированно
  6. 6 Сними новый профиль под той же нагрузкой и сравни с baseline
  7. 7 Убедись, что и локальный hotspot сжался, И headline-метрика улучшилась
Закончи аналогию

Вставь пропуск: широкий фрейм во flame graph называет _______; причина может сидеть уровнем выше (в caller'е), уровнем ниже (в callee) или в том, что функция реально делает.

Вспомните перед уходом
  1. 01
    В одном абзаце: почему назвать горячую функцию недостаточно — что ещё нужно прочесть из профиля, прежде чем её чинить?
  2. 02
    Приведи два конкретных примера, когда правка находится в caller'е, а не в широком leaf'е самом по себе.
Итог

Hot path — это цепочка вызовов, где программа проводит большую часть времени. Широкий leaf во flame graph называет функцию, но причина может быть в caller’е (слишком частые вызовы), в callee (реальная цена уровнем ниже) или в том, что функция делает (CPU-работа vs аллокации vs ожидание). Диагностический вопрос — какая из пяти форм этот hotspot — должен предшествовать выбору правки. Следующие уроки разбирают каждую из пяти форм и соответствующие семейства правок.

Связанные уроки
встречается в159
Продолжить восхождение ↑Пять форм hotspot''''а: CPU, аллокации, кэш, лок, syscall
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.