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
    1. Rastrear resultados de benchmarks a lo largo del tiempo para crear una línea base.
    2. Utilizar esta línea de base junto con umbrales estadísticos para crear un límite estadístico.
    3. Comparar los nuevos resultados contra este límite estadístico para detectar regresiones de rendimiento.
  • Benchmarks Continuos Relativos
    1. Ejecutar los benchmarks para el código de la línea base actual.
    2. Cambiar a la nueva versión del código.
    3. Ejecutar los benchmarks para la nueva versión del código.
    4. Usar umbrales porcentuales para crear un límite para el código de la línea base.
    5. 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
    1. Ocasionalmente ejecutar los benchmarks para nuevas versiones del código.
    2. Usar un algoritmo de detección de cambio de puntos para detectar regresiones de rendimiento.
    3. 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 Save Walter White.

🐰 Asegúrate de haber creado un token de API y configurarlo como la variable de entorno BENCHER_API_TOKEN antes 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:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--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
  1. Utiliza el subcomando CLI bencher run para ejecutar los benchmarks de tu rama main. Ve el subcomando CLI bencher run para una descripción completa. (ej: bencher run)
  2. Establece la opción --project en el slug del Proyecto. Consulta la documentación de --project para más detalles. (ej: --project save-walter-white-1234abcd)
  3. Establece la opción --branch en el nombre de la rama base. Consulta la documentación de --branch para una descripción completa. (ej: --branch main)
  4. Establece la opción --testbed en el nombre del Testbed del runner CI. Consulta la documentación de --testbed para más detalles. (ej: --testbed ci-runner)
  5. Establece el Umbral para la rama main, el Testbed ci-runner y la medida latency:
    1. Establece la opción --threshold-measure en la medida latency incorporada que se genera con bencher mock. Consulta la documentación de --threshold-measure para más detalles. (ej: --threshold-measure latency)
    2. Establece la opción --threshold-test en una prueba t de Student (t_test). Consulta la documentación de --threshold-test para una descripción completa. (ej: --threshold-test t_test)
    3. Establece la opción --threshold-max-sample-size en el tamaño máximo de muestra de 64. Consulta la documentación de --threshold-max-sample-size para más detalles. (ej: --threshold-max-sample-size 64)
    4. Establece la opción --threshold-upper-boundary en el Límite Superior de 0.99. Consulta la documentación de --threshold-upper-boundary para más detalles. (ej: --threshold-upper-boundary 0.99)
    5. Establece la bandera --thresholds-reset para que solo el Umbral especificado esté activo. Consulta la documentación de --thresholds-reset para una descripción completa. (ej: --thresholds-reset)
  6. Establece la bandera --err para que el comando falle si se genera una Alerta. Consulta la documentación de --err para una descripción completa. (ej: --err)
  7. Establece la opción --adapter en Formato Métrico de Bencher JSON (json) que es generado por bencher mock. Consulta adaptadores de arneses de benchmarking para una descripción completa. (ej: --adapter json)
  8. 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:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--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
  1. Utiliza el subcomando CLI bencher run para ejecutar los benchmarks de tu rama feature-branch. Consulta el subcomando CLI bencher run para una descripción completa. (ej: bencher run)
  2. Establece la opción --project en el slug del Proyecto. Consulta la documentación de --project para más detalles. (ej: --project save-walter-white-1234abcd)
  3. Establece la opción --branch en el nombre de la rama de características. Consulta la documentación de --branch para una descripción completa. (ej: --branch feature-branch)
  4. Establece el Punto de Inicio para la rama feature-branch:
    1. Establece la opción --start-point en el punto de inicio de la rama de características. Consulta la documentación de --start-point para una descripción completa. (ej: --start-point main)
    2. Establece la opción --start-point-hash en el hash git del punto de inicio de la rama de características. Consulta la documentación de --start-point-hash para una descripción completa. (ej: --start-point-hash 32ae...dd8b)
    3. Establece la bandera --start-point-clone-thresholds para clonar los Umbrales del punto de inicio. Consulta la documentación de --start-point-clone-thresholds para una descripción completa. (ej: --start-point-clone-thresholds)
    4. Establece la bandera --start-point-reset para siempre restablecer la rama al punto de inicio. Esto evitará el desvío de datos de benchmark. Consulta la documentación de --start-point-reset para una descripción completa. (ej: --start-point-reset)
  5. Establece la opción --testbed en el nombre del Testbed. Consulta la documentación de --tested para más detalles. (ej: --testbed ci-runner)
  6. Establece la bandera --err para que el comando falle si se genera una Alerta. Consulta la documentación de --err para una descripción completa. (ej: --err)
  7. Establece la opción --adapter en Formato Métrico de Bencher JSON (json) que es generado por bencher mock. Consulta adaptadores de arneses de benchmarking para una descripción completa. (ej: --adapter json)
  8. 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_TOKEN antes 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:

Terminal window
git checkout main

Luego necesitamos ejecutar nuestros benchmarks en la rama main en CI:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--branch main \
--start-point-reset \
--testbed ci-runner \
--adapter json \
bencher mock
  1. Usa el subcomando CLI bencher run para ejecutar tus benchmarks de la rama main. Consulta el subcomando CLI bencher run para una descripción completa. (ej: bencher run)
  2. Configura la opción --project al identificador del Proyecto. Consulta la documentación de --project para más detalles. (ej: --project save-walter-white-1234abcd)
  3. Configura la opción --branch al nombre de la rama base. Consulta la documentación de --branch para una visión general completa. (ej: --branch main)
  4. Configura la bandera --start-point-reset para 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-reset para una visión general completa. (ej: --start-point-reset)
  5. Configura la opción --testbed al nombre del banco de pruebas del corredor CI. Consulta la documentación de --testbed para más detalles. (ej: --testbed ci-runner)
  6. Configura la opción --adapter al Formato de Métrica Bencher JSON (json) que es generado por bencher mock. Consulta los adaptadores del arnés de benchmark para una visión general completa. (ej: --adapter json)
  7. 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:

Terminal window
git checkout feature-branch

Finalmente, estamos listos para ejecutar nuestros benchmarks de feature-branch en CI:

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--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
  1. Usa el subcomando CLI bencher run para ejecutar tus benchmarks de feature-branch. Consulta el subcomando CLI bencher run para una descripción completa. (ej: bencher run)
  2. Configura la opción --project al identificador del Proyecto. Consulta la documentación de --project para más detalles. (ej: --project save-walter-white-1234abcd)
  3. Configura la opción --branch al nombre de la rama de características. Consulta la documentación de --branch para una vista general completa. (ej: --branch feature-branch)
  4. Configura el Punto de Inicio para la rama feature-branch:
    1. Configura la opción --start-point al punto de inicio de la rama de características. Consulta la documentación de --start-point para una visión general completa. (ej: --start-point main)
    2. Configura la bandera --start-point-reset para 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-reset para una visión general completa. (ej: --start-point-reset)
  5. Configura la opción --testbed al nombre del banco de pruebas del corredor CI. Consulta la documentación de --testbed para más detalles. (ej: --testbed ci-runner)
  6. Configura el Umbral para la rama feature-branch, banco de pruebas ci-runner y la Medida latency:
    1. Configura la opción --threshold-measure a la Medida integrada latency que es generada por bencher mock. Consulta la documentación de --threshold-measure para más detalles. (ej: --threshold-measure latency)
    2. Configura la opción --threshold-test a un porcentaje básico (percentage). Consulta la documentación de --threshold-test para una visión general completa. (ej: --threshold-test percentage)
    3. Configura la opción --threshold-upper-boundary al Límite Superior de 0.25. Consulta la documentación de --threshold-upper-boundary para más detalles. (ej: --threshold-upper-boundary 0.25)
    4. Configura la bandera --thresholds-reset para que solo el Umbral especificado esté activo. Consulta la documentación de --thresholds-reset para una visión general completa. (ej: --thresholds-reset)
  7. Configura la bandera --err para que falle el comando si se genera una Alerta. Consulta la documentación de --err para una visión general completa. (ej: --err)
  8. Configura la opción --adapter al Formato de Métrica Bencher JSON (json) que es generado por bencher mock. Consulta los adaptadores del arnés de benchmark para una visión general completa. (ej: --adapter json)
  9. 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! 🎉


Agregar Bencher a GitHub Actions ➡

Agregar Bencher a GitLab CI/CD ➡

🤖 Este documento fue generado automáticamente por OpenAI GPT-4. Puede que no sea exacto y contenga errores. Si encuentra algún error, abra un problema en GitHub.


Published: Fri, October 27, 2023 at 8:40:00 AM UTC | Last Updated: Mon, November 11, 2024 at 7:45:00 AM UTC