Cómo seguir los benchmarks en CI con Bencher
La mayoría de los resultados de los benchmarks son efímeros. Desaparecen tan pronto como tu terminal alcanza su límite de retroceso. Algunos entornos de benchmarks te permiten almacenar resultados en caché, pero la mayoría solo lo hace localmente. Bencher te permite rastrear tus benchmarks de ejecuciones locales y de CI y comparar los resultados, mientras sigues usando tu entorno de benchmarks favorito.
Hay tres formas populares de comparar resultados de benchmarks cuando se realizan benchmarks continuos, es decir, benchmarks en CI:
- Benchmarks Continuos Estadísticos
- Rastrear resultados de benchmarks a lo largo del tiempo para crear una línea base.
- Utilizar esta línea de base junto con umbrales estadísticos para crear un límite estadístico.
- Comparar los nuevos resultados contra este límite estadístico para detectar regresiones de rendimiento.
- Benchmarks Continuos Relativos
- Ejecutar los benchmarks para el código de la línea base actual.
- Cambiar a la nueva versión del código.
- Usar umbrales porcentuales para crear un límite para el código de la línea base.
- Ejecutar los benchmarks para la nueva versión del código.
- Comparar los resultados de la nueva versión del código contra los resultados del código base para detectar regresiones de rendimiento.
- Detección de Cambio de Puntos
- Ocasionalmente ejecutar los benchmarks para nuevas versiones del código.
- Usar un algoritmo de detección de cambio de puntos para detectar regresiones de rendimiento.
- Usar bisección para encontrar el commit que introdujo la regresión de rendimiento.
Benchmarking Continuo Estadístico
Retomando donde lo dejamos en los tutoriales de
Inicio Rápido y Auto hospedado en Docker,
agreguemos Benchmarking Continuo Estadístico a nuestro proyecto claimed.
🐰 Asegúrate de haber creado un token de API y configurarlo como la variable de entorno
BENCHER_API_TOKENantes de continuar.
Ahora estamos listos para ejecutar nuestros benchmarks en CI. Debido a que cada entorno de CI es un poco diferente, el siguiente ejemplo tiene la intención de ser más ilustrativo que práctico. Para ejemplos más específicos, consulta Benchmarking Continuo en GitHub Actions y Benchmarking Continuo en GitLab CI/CD.
Primero, necesitamos crear y mantener una línea base histórica para nuestra rama main haciendo benchmarking de cada cambio en CI:
bencher run \--project project-abc4567-wxyz123456789 \--branch main \--testbed ci-runner \--threshold-measure latency \--threshold-test t_test \--threshold-max-sample-size 64 \--threshold-upper-boundary 0.99 \--thresholds-reset \--err \--adapter json \bencher mock- Utiliza el subcomando CLI
bencher runpara ejecutar los benchmarks de tu ramamain. Ve el subcomando CLIbencher runpara una descripción completa. (ej:bencher run) - Establece la opción
--projecten el slug del Proyecto. Consulta la documentación de--projectpara más detalles. (ej:--project project-abc4567-wxyz123456789) - Establece la opción
--branchen el nombre de la rama base. Consulta la documentación de--branchpara una descripción completa. (ej:--branch main) - Establece la opción
--testbeden el nombre del Testbed del runner CI. Consulta la documentación de--testbedpara más detalles. (ej:--testbed ci-runner) - Establece el Umbral para la rama
main, el Testbedci-runnery la medidalatency:- Establece la opción
--threshold-measureen la medidalatencyincorporada que se genera conbencher mock. Consulta la documentación de--threshold-measurepara más detalles. (ej:--threshold-measure latency) - Establece la opción
--threshold-testen una prueba t de Student (t_test). Consulta la documentación de--threshold-testpara una descripción completa. (ej:--threshold-test t_test) - Establece la opción
--threshold-max-sample-sizeen el tamaño máximo de muestra de64. Consulta la documentación de--threshold-max-sample-sizepara más detalles. (ej:--threshold-max-sample-size 64) - Establece la opción
--threshold-upper-boundaryen el Límite Superior de0.99. Consulta la documentación de--threshold-upper-boundarypara más detalles. (ej:--threshold-upper-boundary 0.99) - Establece la bandera
--thresholds-resetpara que solo el Umbral especificado esté activo. Consulta la documentación de--thresholds-resetpara una descripción completa. (ej:--thresholds-reset)
- Establece la opción
- Establece la bandera
--errpara que el comando falle si se genera una Alerta. Consulta la documentación de--errpara una descripción completa. (ej:--err) - Establece la opción
--adapteren Formato Métrico de Bencher JSON (json) que es generado porbencher mock. Consulta adaptadores de arneses de benchmarking para una descripción completa. (ej:--adapter json) - Especifica los argumentos del comando de benchmark.
Consulta el comando de benchmark para una descripción completa.
(ej:
bencher mock)
La primera vez que este comando se ejecuta en CI,
creará la rama main si aún no existe.
La nueva main no tendrá un punto de inicio ni datos existentes.
Se creará un Umbral para la rama main, el Testbed ci-runner y la medida latency.
En ejecuciones posteriores, se agregarán nuevos datos a la rama main.
El Umbral especificado luego se usará para detectar regresiones de rendimiento.
Ahora, estamos listos para detectar regresiones de rendimiento en CI.
Así es como rastrearíamos el rendimiento de una nueva rama de características en CI, apropiadamente llamada feature-branch:
bencher run \--project project-abc4567-wxyz123456789 \--branch feature-branch \--start-point main \--start-point-hash 32aea434d751648726097ed3ac760b57107edd8b \--start-point-clone-thresholds \--start-point-reset \--testbed ci-runner \--err \--adapter json \bencher mock- Utiliza el subcomando CLI
bencher runpara ejecutar los benchmarks de tu ramafeature-branch. Consulta el subcomando CLIbencher runpara una descripción completa. (ej:bencher run) - Establece la opción
--projecten el slug del Proyecto. Consulta la documentación de--projectpara más detalles. (ej:--project project-abc4567-wxyz123456789) - Establece la opción
--branchen el nombre de la rama de características. Consulta la documentación de--branchpara una descripción completa. (ej:--branch feature-branch) - Establece el Punto de Inicio para la rama
feature-branch:- Establece la opción
--start-pointen el punto de inicio de la rama de características. Consulta la documentación de--start-pointpara una descripción completa. (ej:--start-point main) - Establece la opción
--start-point-hashen el hashgitdel punto de inicio de la rama de características. Consulta la documentación de--start-point-hashpara una descripción completa. (ej:--start-point-hash 32ae...dd8b) - Establece la bandera
--start-point-clone-thresholdspara clonar los Umbrales del punto de inicio. Consulta la documentación de--start-point-clone-thresholdspara una descripción completa. (ej:--start-point-clone-thresholds) - Establece la bandera
--start-point-resetpara siempre restablecer la rama al punto de inicio. Esto evitará el desvío de datos de benchmark. Consulta la documentación de--start-point-resetpara una descripción completa. (ej:--start-point-reset)
- Establece la opción
- Establece la opción
--testbeden el nombre del Testbed. Consulta la documentación de--testedpara más detalles. (ej:--testbed ci-runner) - Establece la bandera
--errpara que el comando falle si se genera una Alerta. Consulta la documentación de--errpara una descripción completa. (ej:--err) - Establece la opción
--adapteren Formato Métrico de Bencher JSON (json) que es generado porbencher mock. Consulta adaptadores de arneses de benchmarking para una descripción completa. (ej:--adapter json) - Especifica los argumentos del comando de benchmark.
Consulta el comando de benchmark para una descripción completa.
(ej:
bencher mock)
La primera vez que este comando se ejecuta en CI,
Bencher creará la rama feature-branch ya que aún no existe.
La nueva feature-branch usará la rama main
en el hash 32aea434d751648726097ed3ac760b57107edd8b como su punto de inicio.
Esto significa que feature-branch tendrá una copia de todos los datos y Umbrales
de la rama main para comparar los resultados de bencher mock.
En todas las ejecuciones posteriores, Bencher restablecerá la rama feature-branch al punto de inicio,
y usará los datos y Umbrales de la rama main para detectar regresiones de rendimiento.
Benchmarking Continuo Relativo
Retomando desde donde lo dejamos en los tutoriales de
Inicio Rápido y Autohospedado con Docker,
vamos a agregar Benchmarking Continuo Relativo a nuestro proyecto Salvar a Walter White.
🐰 Asegúrate de haber creado un token de API y configurado como la variable de entorno
BENCHER_API_TOKENantes de continuar.
El Benchmarking Continuo Relativo realiza una comparación lado a lado de dos versiones de tu código.
Esto puede ser útil en entornos CI/CD ruidosos,
donde los recursos disponibles pueden ser altamente variables entre ejecuciones.
En este ejemplo, compararemos los resultados de ejecutar en la rama main
con los resultados de ejecutar en una rama de características, apropiadamente llamada feature-branch.
Debido a que cada entorno de CI es un poco diferente,
el siguiente ejemplo está destinado a ser más ilustrativo que práctico.
Para ejemplos más específicos, consulta Benchmarking Continuo en GitHub Actions
y Benchmarking Continuo en GitLab CI/CD.
Primero, necesitamos obtener la rama main con git en CI:
git checkout mainLuego necesitamos ejecutar nuestros benchmarks en la rama main en CI:
bencher run \--project project-abc4567-wxyz123456789 \--branch main \--start-point-reset \--testbed ci-runner \--adapter json \bencher mock- Usa el subcomando CLI
bencher runpara ejecutar tus benchmarks de la ramamain. Consulta el subcomando CLIbencher runpara una descripción completa. (ej:bencher run) - Configura la opción
--projectal identificador del Proyecto. Consulta la documentación de--projectpara más detalles. (ej:--project project-abc4567-wxyz123456789) - Configura la opción
--branchal nombre de la rama base. Consulta la documentación de--branchpara una visión general completa. (ej:--branch main) - Configura la bandera
--start-point-resetpara siempre reiniciar la rama base. Esto asegurará que todo el dato de benchmark provenga del corredor actual de CI. Consulta la documentación de--start-point-resetpara una visión general completa. (ej:--start-point-reset) - Configura la opción
--testbedal nombre del banco de pruebas del corredor CI. Consulta la documentación de--testbedpara más detalles. (ej:--testbed ci-runner) - Configura la opción
--adapteral Formato de Métrica Bencher JSON (json) que es generado porbencher mock. Consulta los adaptadores del arnés de benchmark para una visión general completa. (ej:--adapter json) - Especifica los argumentos del comando de benchmark.
Consulta el comando de benchmark para una visión general completa.
(ej:
bencher mock)
La primera vez que se ejecuta este comando en CI,
creará la rama main ya que todavía no existe.
La nueva main no tendrá un punto de inicio, datos existentes ni Umbrales.
En ejecuciones posteriores, el antiguo Movimiento Head de main será reemplazado
y se creará un nuevo Movimiento Head para main sin un punto de inicio, datos existentes ni Umbrales.
Luego, necesitamos obtener la rama feature-branch con git en CI:
git checkout feature-branchFinalmente, estamos listos para ejecutar nuestros benchmarks de feature-branch en CI:
bencher run \--project project-abc4567-wxyz123456789 \--branch feature-branch \--start-point main \--start-point-reset \--testbed ci-runner \--threshold-measure latency \--threshold-test percentage \--threshold-upper-boundary 0.25 \--thresholds-reset \--err \--adapter json \bencher mock- Usa el subcomando CLI
bencher runpara ejecutar tus benchmarks defeature-branch. Consulta el subcomando CLIbencher runpara una descripción completa. (ej:bencher run) - Configura la opción
--projectal identificador del Proyecto. Consulta la documentación de--projectpara más detalles. (ej:--project project-abc4567-wxyz123456789) - Configura la opción
--branchal nombre de la rama de características. Consulta la documentación de--branchpara una vista general completa. (ej:--branch feature-branch) - Configura el Punto de Inicio para la rama
feature-branch:- Configura la opción
--start-pointal punto de inicio de la rama de características. Consulta la documentación de--start-pointpara una visión general completa. (ej:--start-point main) - Configura la bandera
--start-point-resetpara siempre reiniciar la rama al punto de inicio. Esto usará solo los resultados de benchmark más recientes y relativos. Consulta la documentación de--start-point-resetpara una visión general completa. (ej:--start-point-reset)
- Configura la opción
- Configura la opción
--testbedal nombre del banco de pruebas del corredor CI. Consulta la documentación de--testbedpara más detalles. (ej:--testbed ci-runner) - Configura el Umbral para la rama
feature-branch, banco de pruebasci-runnery la Medidalatency:- Configura la opción
--threshold-measurea la Medida integradalatencyque es generada porbencher mock. Consulta la documentación de--threshold-measurepara más detalles. (ej:--threshold-measure latency) - Configura la opción
--threshold-testa un porcentaje básico (percentage). Consulta la documentación de--threshold-testpara una visión general completa. (ej:--threshold-test percentage) - Configura la opción
--threshold-upper-boundaryal Límite Superior de0.25. Consulta la documentación de--threshold-upper-boundarypara más detalles. (ej:--threshold-upper-boundary 0.25) - Configura la bandera
--thresholds-resetpara que solo el Umbral especificado esté activo. Consulta la documentación de--thresholds-resetpara una visión general completa. (ej:--thresholds-reset)
- Configura la opción
- Configura la bandera
--errpara que falle el comando si se genera una Alerta. Consulta la documentación de--errpara una visión general completa. (ej:--err) - Configura la opción
--adapteral Formato de Métrica Bencher JSON (json) que es generado porbencher mock. Consulta los adaptadores del arnés de benchmark para una visión general completa. (ej:--adapter json) - Especifica los argumentos del comando de benchmark.
Consulta el comando de benchmark para una visión general completa.
(ej:
bencher mock)
Cada vez que se ejecuta este comando en CI,
compara los resultados de feature-branch solo contra los resultados más recientes de main.
El Umbral especificado se utiliza luego para detectar regresiones de rendimiento.
Detección de Puntos de Cambio
La Detección de Puntos de Cambio utiliza un algoritmo de detección de cambio para evaluar una gran ventana de resultados recientes. Esto permite que el algoritmo ignore valores atípicos como ruido y produzca menos falsos positivos. Aunque la Detección de Puntos de Cambio se considera evaluación continua, no te permite detectar regresiones de rendimiento en CI. Es decir, no puedes detectar una regresión de rendimiento antes de que se fusione una rama de características. Esto a veces se denomina detección “fuera de banda”.
Por ejemplo, si tienes una prueba de referencia bench_my_critical_path, y ha tenido las siguientes latencias históricas: 5 ms, 6 ms, 5 ms, 5 ms, 7 ms.
Si el siguiente resultado de la prueba de referencia fuera 11 ms, un umbral de Evaluación Estadística Continua y el algoritmo de Detección de Puntos de Cambio interpretarían las cosas de manera muy diferente. Es probable que se superara el umbral y se generara una alerta. Si esta ejecución de referencia estuviera vinculada a una solicitud de extracción, es probable que la construcción se estableciera para fallar debido a esta alerta. Sin embargo, el algoritmo de punto de cambio no haría nada… todavía. Si la siguiente ejecución vuelve a bajar a 5 ms entonces probablemente no generaría una alerta. Por el contrario, si los próximos resultados fueran 10 ms y 12 ms, solo entonces el algoritmo de punto de cambio activaría una alerta.
¿Estás interesado en usar la Detección de Puntos de Cambio con Bencher? Si es así, por favor deja un comentario en el problema de seguimiento o contáctanos directamente.
🐰 ¡Felicidades! Has aprendido cómo seguir los benchmarks en CI con Bencher! 🎉