Как отслеживать бенчмарки в CI с помощью Bencher
Большинство результатов тестов производительности являются эфемерными. Они исчезают, как только ваш терминал достигает предела прокрутки. Некоторые фреймворки для тестирования позволяют кешировать результаты, но большинство из них делают это только локально. Bencher позволяет отслеживать ваши тесты как с локальных, так и с CI-запусков и сравнивать результаты, при этом вы всё ещё можете использовать ваш любимый фреймворк для тестирования.
Существует три популярных способа сравнения результатов тестов производительности при непрерывном тестировании производительности, то есть тестировании производительности в CI:
- Статистическое непрерывное тестирование
- Отслеживайте результаты тестов производительности с течением времени для создания базового уровня
- Используйте этот базовый уровень вместе с статистическими порогами для создания статистической границы
- Сравните новые результаты с этой статистической границей для обнаружения регрессий производительности
- Относительное непрерывное тестирование
- Выполните тесты производительности для текущего базового кода
- Переключитесь на новую версию кода
- Выполните тесты производительности для новой версии кода
- Используйте процентные пороги для создания границы для базового кода
- Сравните результаты новой версии кода с результатами базового кода для обнаружения регрессий производительности
- Обнаружение точек изменений
- Периодически выполняйте тесты производительности для новых версий кода
- Используйте алгоритм обнаружения точек изменений для выявления регрессий производительности
- Выполните бисекцию, чтобы найти коммит, который привёл к регрессии производительности
Статистическое непрерывное тестирование производительности
Продолжая с того места, где мы остановились в
Быстром старте и Локальном использовании Docker,
давайте добавим статистическое непрерывное тестирование производительности нашему проекту Save Walter White
.
🐰 Перед продолжением убедитесь, что вы создали API токен и установили его в качестве переменной среды
BENCHER_API_TOKEN
!
Теперь мы готовы запускать наши тесты производительности в CI. Поскольку каждая среда CI немного отличается, следующий пример предназначен скорее для иллюстрации, чем для практического использования. Для более специфичных примеров смотрите Непрерывное тестирование производительности в GitHub Actions и Непрерывное тестирование производительности в GitLab CI/CD.
Во-первых, нам нужно создать и поддерживать историческую базовую линию для нашей ветви main
, тестируя каждое изменение в CI:
- Используйте подкоманду CLI
bencher run
для запуска тестов производительности вашей ветвиmain
. Полный обзор смотрите в подкоманде CLIbencher run
. (например:bencher run
) - Установите опцию
--project
в проектный ярлык. Подробнее смотрите в документации по опции--project
. (например:--project save-walter-white-1234abcd
) - Установите опцию
--branch
в имя базовой ветви. Полный обзор смотрите в документации по опции--branch
. (например:--branch main
) - Установите опцию
--testbed
в название тестовой среды CI. Подробнее смотрите в документации по опции--testbed
. (например:--testbed ci-runner
) - Установите порог для ветви
main
, тестовой средыci-runner
и измеренияlatency
:- Установите опцию
--threshold-measure
в встроенное измерениеlatency
, создаваемоеbencher mock
. Подробнее смотрите в документации по опции--threshold-measure
. (например:--threshold-measure latency
) - Установите опцию
--threshold-test
в тест Стьюдента (t_test
). Полный обзор смотрите в документации по опции--threshold-test
. (например:--threshold-test t_test
) - Установите опцию
--threshold-max-sample-size
на максимальный размер выборки64
. Подробнее смотрите в документации по опции--threshold-max-sample-size
. (например:--threshold-max-sample-size 64
) - Установите опцию
--threshold-upper-boundary
на верхнюю границу0.99
. Подробнее смотрите в документации по опции--threshold-upper-boundary
. (например:--threshold-upper-boundary 0.99
) - Установите флаг
--thresholds-reset
, чтобы только указанный порог был активен. Полный обзор смотрите в документации по флагу--thresholds-reset
. (например:--thresholds-reset
)
- Установите опцию
- Установите флаг
--err
для завершения команды в случае возникновения предупреждения. Полный обзор смотрите в документации по флагу--err
. (например:--err
) - Установите опцию
--adapter
в формат Bencher Metric JSON (json
), который создаетсяbencher mock
. Полный обзор смотрите в адаптеры теста. (например:--adapter json
) - Укажите аргументы команды тестирования.
Полный обзор смотрите в команда тестирования.
(например:
bencher mock
)
Первый запуск этой команды в CI создаст ветвь main
, если она еще не существует.
Новая main
не будет иметь начальной точки или существующих данных.
Для ветви main
, тестовой среды ci-runner
и измерения latency
будет создан порог.
На последующих запусках новые данные будут добавляться в ветвь main
.
Указанный порог будет использоваться для обнаружения регрессий производительности.
Теперь мы готовы выявлять регрессии производительности в CI.
Вот как мы будем отслеживать производительность новой ветви функций в CI, именуемой feature-branch
:
- Используйте подкоманду CLI
bencher run
для запуска тестов производительности вашей ветвиfeature-branch
. Полный обзор смотрите в подкоманде CLIbencher run
. (например:bencher run
) - Установите опцию
--project
в проектный ярлык. Подробнее смотрите в документации по опции--project
. (например:--project save-walter-white-1234abcd
) - Установите опцию
--branch
в имя ветви функции. Полный обзор смотрите в документации по опции--branch
. (например:--branch feature-branch
) - Установите начальную точку для ветви
feature-branch
:- Установите опцию
--start-point
на начальную точку ветви функции. Полный обзор смотрите в документации по опции--start-point
. (например:--start-point main
) - Установите опцию
--start-point-hash
на хэшgit
начальной точки ветви функции. Полный обзор смотрите в документации по опции--start-point-hash
. (например:--start-point-hash 32ae...dd8b
) - Установите флаг
--start-point-clone-thresholds
для клонирования порогов из начальной точки. Полный обзор смотрите в документации по флагу--start-point-clone-thresholds
. (например:--start-point-clone-thresholds
) - Установите флаг
--start-point-reset
для постоянного сброса ветви к начальной точке. Это предотвратит смещение данных тестирования. Полный обзор смотрите в документации по флагу--start-point-reset
. (например:--start-point-reset
)
- Установите опцию
- Установите опцию
--testbed
в название тестовой среды. Подробнее смотрите в документации по опции--testbed
. (например:--testbed ci-runner
) - Установите флаг
--err
для завершения команды в случае возникновения предупреждения. Полный обзор смотрите в документации по флагу--err
. (например:--err
) - Установите опцию
--adapter
в формат Bencher Metric JSON (json
), который создаетсяbencher mock
. Полный обзор смотрите в адаптеры теста. (например:--adapter json
) - Укажите аргументы команды тестирования.
Полный обзор смотрите в команда тестирования.
(например:
bencher mock
)
Первый запуск этой команды в CI заставит Bencher создать ветвь feature-branch
, поскольку она пока не существует.
Новая ветвь feature-branch
будет использовать ветвь main
с хэшем 32aea434d751648726097ed3ac760b57107edd8b
в качестве начальной точки.
Это означает, что feature-branch
будет иметь копию всех данных и порогов
из ветви main
для сравнения результатов bencher mock
.
На всех последующих запусках Bencher сбросит ветвь feature-branch
к начальной точке,
и будет использовать данные и пороги ветви main
для обнаружения регрессий производительности.
Относительное Непрерывное Бенчмаркинг
Продолжая с того места, где мы остановились в
Руководствах Быстрого Старта и Docker для Самостоятельного Развертывания,
давайте добавим Относительное Непрерывное Бенчмаркинг в наш проект Save Walter White
.
🐰 Убедитесь, что вы создали токен API и установите его в качестве переменной окружения
BENCHER_API_TOKEN
перед продолжением!
Относительное Непрерывное Бенчмаркинг выполняет сравнительный анализ двух версий вашего кода.
Это может быть полезно при работе с шумными средами CI/CD,
где доступные ресурсы могут быть высоко изменчивыми между запусками.
В этом примере мы будем сравнивать результаты запуска на ветке main
с результатами запуска на отдельно взятой ветке, подходяще названной feature-branch
.
Поскольку каждая среда CI немного отличается,
следующий пример предназначен скорее для иллюстрации, чем для практического применения.
Для более конкретных примеров см. Непрерывное Бенчмаркинг в GitHub Actions
и Непрерывное Бенчмаркинг в GitLab CI/CD.
Сначала нам нужно переключиться на ветку main
с помощью git
в CI:
Затем нам нужно запустить наши бенчмарки на ветке main
в CI:
- Используйте
bencher run
команду CLI, чтобы запустить ваши бенчмарки для веткиmain
. Смотрите командуbencher run
CLI для полного обзора. (например:bencher run
) - Установите опцию
--project
на слаг Проекта. Смотрите документацию по--project
для более подробной информации. (например:--project save-walter-white-1234abcd
) - Установите опцию
--branch
на имя основной ветки. Смотрите документацию по--branch
для полного обзора. (например:--branch main
) - Установите флаг
--start-point-reset
для всегда сбрасываемой основной ветки. Это обеспечит, что все данные бенчмарка будут получены с текущего CI-раннера. Смотрите документацию по--start-point-reset
для полного обзора. (например:--start-point-reset
) - Установите опцию
--testbed
на имя Testbed CI-раннера. Смотрите документацию по--testbed
для более подробной информации. (например:--testbed ci-runner
) - Установите опцию
--adapter
на Bencher Metric Format JSON (json
), который генерируетсяbencher mock
. Смотрите адаптеры для бенчмаркинга для полного обзора. (например:--adapter json
) - Укажите аргументы команды бенчмарка.
Смотрите документацию команды бенчмарка для полного обзора.
(например:
bencher mock
)
Первый раз, когда эта команда будет выполнена в CI,
она создаст ветку main
, так как она еще не существует.
Новая main
не будет иметь начальной точки, существующих данных или Порогов.
При последующих запусках старая main
Head будет заменена,
а новая main
Head будет создана без начальной точки, существующих данных или Порогов.
Далее, нам нужно переключиться на ветку feature-branch
с помощью git
в CI:
Теперь мы готовы выполнить наши бенчмарки для feature-branch
в CI:
- Используйте
bencher run
команду CLI, чтобы запустить ваши бенчмарки дляfeature-branch
. Смотрите командуbencher run
CLI для полного обзора. (например:bencher run
) - Установите опцию
--project
на слаг Проекта. Смотрите документацию по--project
для более подробной информации. (например:--project save-walter-white-1234abcd
) - Установите опцию
--branch
на имя ветки feature-branch. Смотрите документацию по--branch
для полного обзора. (например:--branch feature-branch
) - Установите начальную точку для ветки
feature-branch
:- Установите опцию
--start-point
на начальную точку ветки feature. Смотрите документацию по--start-point
для полного обзора. (например:--start-point main
) - Установите флаг
--start-point-reset
, чтобы всегда сбрасывать ветку к начальному пункту. Это позволит использовать только самые последние результаты относительного бенчмарка. Смотрите документацию по--start-point-reset
для полного обзора. (например:--start-point-reset
)
- Установите опцию
- Установите опцию
--testbed
на имя Testbed CI-раннера. Смотрите документацию по--testbed
для более подробной информации. (например:--testbed ci-runner
) - Установите Порог для ветки
feature-branch
, Testbedci-runner
и Мерыlatency
:- Установите опцию
--threshold-measure
на встроенную Меруlatency
, которая генерируетсяbencher mock
. Смотрите документацию по--threshold-measure
для более подробной информации. (например:--threshold-measure latency
) - Установите опцию
--threshold-test
на основной процент (percentage
). Смотрите документацию по--threshold-test
для полного обзора. (например:--threshold-test percentage
) - Установите опцию
--threshold-upper-boundary
на Верхнюю Границу0.25
. Смотрите документацию по--threshold-upper-boundary
для более подробной информации. (например:--threshold-upper-boundary 0.25
) - Установите флаг
--thresholds-reset
, так чтобы был активен только указанный Порог. Смотрите документацию по--thresholds-reset
для полного обзора. (например:--thresholds-reset
)
- Установите опцию
- Установите флаг
--err
, чтобы команда завершалась с ошибкой, если генерируется Предупреждение. Смотрите документацию по--err
для полного обзора. (например:--err
) - Установите опцию
--adapter
на Bencher Metric Format JSON (json
), который генерируетсяbencher mock
. Смотрите адаптеры для бенчмаркинга для полного обзора. (например:--adapter json
) - Укажите аргументы команды бенчмарка.
Смотрите документацию команды бенчмарка для полного обзора.
(например:
bencher mock
)
Каждый раз, когда эта команда выполняется в CI,
она сравнивает результаты feature-branch
только с самыми последними результатами main
.
Указанный Порог используется для обнаружения регрессий производительности.
Обнаружение точек изменений
Обнаружение точек изменений использует алгоритм обнаружения изменений для оценки большого окна недавних результатов. Это позволяет алгоритму игнорировать выбросы как шум и снижать количество ложноположительных срабатываний. Хотя обнаружение точек изменений считается непрерывным сравнительным анализом, оно не позволяет обнаруживать регрессии производительности в CI. То есть, вы не можете обнаружить регрессию производительности до слияния ветки функции. Это иногда называют “внесистемным” обнаружением.
Например, если у вас есть тест bench_my_critical_path
,
и у него были следующие исторические задержки: 5 ms
, 6 ms
, 5 ms
, 5ms
, 7ms
.
Если следующий результат теста составил 11 ms
, то порог статистического непрерывного сравнительного анализа
и алгоритм обнаружения точек изменений интерпретировали бы это по-разному.
Порог, вероятно, был бы превышен, и было бы сгенерировано предупреждение.
Если этот прогон теста был связан с pull-запросом,
сборка, вероятно, была бы помечена как неудачная из-за этого предупреждения.
Однако, алгоритм точек изменений не сделал бы ничего… пока.
Если бы в следующий прогон результаты вернулись к 5 ms
, то, вероятно, предупреждение не было бы сгенерировано.
Наоборот, если бы один-два следующих прогона дали результаты 10 ms
и 12 ms
,
только тогда алгоритм точек изменений сгенерировал бы предупреждение.
Заинтересованы в использовании обнаружения точек изменений с Bencher? Если да, оставьте комментарий по трековому вопросу или свяжитесь с нами напрямую.
🐰 Поздравляем! Вы научились отслеживать бенчмарки в CI с помощью Bencher! 🎉