Comment Suivre les Benchmarks dans l'Intégration Continue avec Bencher


La plupart des résultats de benchmarks sont éphémères. Ils disparaissent dès que votre terminal atteint sa limite de défilement. Certains environnements de test vous permettent de mettre en cache les résultats, mais la plupart ne le font que localement. Bencher vous permet de suivre vos benchmarks à partir des exécutions locales et CI et de comparer les résultats, tout en utilisant votre environnement de test préféré.

Il existe trois méthodes populaires pour comparer les résultats des benchmarks lors de l’évaluation continue des performances, c’est-à-dire le benchmarking en CI :

  • Évaluation continue statistique des performances
    1. Suivre les résultats des benchmarks dans le temps pour créer une base de référence
    2. Utiliser cette base de référence avec des seuils statistiques pour créer une frontière statistique
    3. Comparer les nouveaux résultats à cette frontière statistique pour détecter les régressions de performance
  • Évaluation continue relative des performances
    1. Exécuter les benchmarks pour le code de base actuel
    2. Passer à la nouvelle version du code
    3. Exécuter les benchmarks pour la nouvelle version du code
    4. Utiliser des seuils de pourcentage pour créer une frontière pour le code de base
    5. Comparer les résultats de la nouvelle version du code avec ceux du code de base pour détecter les régressions de performance
  • Détection de point de changement
    1. Exécuter occasionnellement les benchmarks pour les nouvelles versions du code
    2. Utiliser un algorithme de détection de point de changement pour détecter les régressions de performance
    3. Faire une bisection pour trouver le commit qui a introduit la régression de performance

Benchmarking Continu Statistique

Partant de là où nous en étions dans les tutoriels Quick Start et Docker Self-Hosted, ajoutons le Benchmarking Continu Statistique à notre projet Save Walter White.

🐰 Assurez-vous d’avoir créé un jeton API et de l’avoir défini comme variable d’environnement BENCHER_API_TOKEN avant de continuer !

Nous sommes maintenant prêts à exécuter nos benchmarks dans CI. Étant donné que chaque environnement CI est un peu différent, l’exemple suivant est conçu pour être plus illustratif que pratique. Pour des exemples plus spécifiques, consultez Benchmarking Continu dans GitHub Actions et Benchmarking Continu dans GitLab CI/CD.

Tout d’abord, nous devons créer et maintenir une référence historique pour notre branche main en évaluant chaque changement dans 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. Utilisez la sous-commande CLI bencher run pour exécuter les benchmarks de votre branche main. Voir la sous-commande CLI bencher run pour un aperçu complet. (ex: bencher run)
  2. Définissez l’option --project sur le slug du Projet. Voir la documentation --project pour plus de détails. (ex: --project save-walter-white-1234abcd)
  3. Définissez l’option --branch sur le nom de la branche de base. Voir la documentation --branch pour un aperçu complet. (ex: --branch main)
  4. Définissez l’option --testbed sur le nom du Testbed du coureur CI. Voir la documentation --testbed pour plus de détails. (ex: --testbed ci-runner)
  5. Définissez le Seuil pour la branche main, le Testbed ci-runner et la Mesure latency :
    1. Définissez l’option --threshold-measure sur la Mesure latency intégrée générée par bencher mock. Voir la documentation --threshold-measure pour plus de détails. (ex: --threshold-measure latency)
    2. Définissez l’option --threshold-test sur un test t de Student (t_test). Voir la documentation --threshold-test pour un aperçu complet. (ex: --threshold-test t_test)
    3. Définissez l’option --threshold-max-sample-size sur la taille d’échantillon maximale de 64. Voir la documentation --threshold-max-sample-size pour plus de détails. (ex: --threshold-max-sample-size 64)
    4. Définissez l’option --threshold-upper-boundary sur la Limite Supérieure de 0.99. Voir la documentation --threshold-upper-boundary pour plus de détails. (ex: --threshold-upper-boundary 0.99)
    5. Activez le drapeau --thresholds-reset pour que seul le Seuil spécifié soit actif. Voir la documentation --thresholds-reset pour un aperçu complet. (ex: --thresholds-reset)
  6. Activez le drapeau --err pour que la commande échoue si une Alerte est générée. Voir la documentation --err pour un aperçu complet. (ex: --err)
  7. Définissez l’option --adapter sur Bencher Metric Format JSON (json) généré par bencher mock. Voir les adaptateurs de harnais de benchmark pour un aperçu complet. (ex: --adapter json)
  8. Spécifiez les arguments de commande de benchmark. Voir commande de benchmark pour un aperçu complet. (ex: bencher mock)

La première fois que cette commande est exécutée dans CI, elle créera la branche main si elle n’existe pas encore. La nouvelle main n’aura pas de point de départ ni de données existantes. Un Seuil sera créé pour la branche main, le Testbed ci-runner et la Mesure latency. Lors des exécutions ultérieures, de nouvelles données seront ajoutées à la branche main. Le Seuil spécifié sera ensuite utilisé pour détecter les régressions de performance.

Nous sommes maintenant prêts à détecter les régressions de performance dans CI. Voici comment nous suivrions les performances d’une nouvelle branche de fonctionnalités dans CI, judicieusement nommée 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. Utilisez la sous-commande CLI bencher run pour exécuter les benchmarks de votre branche feature-branch. Voir la sous-commande CLI bencher run pour un aperçu complet. (ex: bencher run)
  2. Définissez l’option --project sur le slug du Projet. Voir la documentation --project pour plus de détails. (ex: --project save-walter-white-1234abcd)
  3. Définissez l’option --branch sur le nom de la branche de fonctionnalité. Voir la documentation --branch pour un aperçu complet. (ex: --branch feature-branch)
  4. Définissez le Point de Départ pour la branche feature-branch :
    1. Définissez l’option --start-point sur le point de départ de la branche de fonctionnalité. Voir la documentation --start-point pour un aperçu complet. (ex: --start-point main)
    2. Définissez l’option --start-point-hash sur le hachage git du point de départ de la branche de fonctionnalité. Voir la documentation --start-point-hash pour un aperçu complet. (ex: --start-point-hash 32ae...dd8b)
    3. Activez le drapeau --start-point-clone-thresholds pour cloner les Seuils du point de départ. Voir la documentation --start-point-clone-thresholds pour un aperçu complet. (ex: --start-point-clone-thresholds)
    4. Activez le drapeau --start-point-reset pour toujours réinitialiser la Branche au point de départ. Cela empêchera la dérive des données de benchmark. Voir la documentation --start-point-reset pour un aperçu complet. (ex: --start-point-reset)
  5. Définissez l’option --testbed sur le nom du Testbed. Voir la documentation --tested pour plus de détails. (ex: --testbed ci-runner)
  6. Activez le drapeau --err pour que la commande échoue si une Alerte est générée. Voir la documentation --err pour un aperçu complet. (ex: --err)
  7. Définissez l’option --adapter sur Bencher Metric Format JSON (json) généré par bencher mock. Voir les adaptateurs de harnais de benchmark pour un aperçu complet. (ex: --adapter json)
  8. Spécifiez les arguments de commande de benchmark. Voir commande de benchmark pour un aperçu complet. (ex: bencher mock)

La première fois que cette commande est exécutée dans CI, Bencher créera la branche feature-branch car elle n’existe pas encore. La nouvelle branche feature-branch utilisera la branche main au hachage 32aea434d751648726097ed3ac760b57107edd8b comme point de départ. Cela signifie que feature-branch aura une copie de toutes les données et Seuils de la branche main pour comparer les résultats de bencher mock. Lors de toutes les exécutions ultérieures, Bencher réinitialisera la branche feature-branch au point de départ, et utilisera les données et les Seuils de la branche main pour détecter les régressions de performance.

Benchmarking Continu Relatif

En reprenant là où nous nous étions arrêtés dans les tutoriels Démarrage Rapide et Docker Auto-Hébergé, ajoutons le Benchmarking Continu Relatif à notre projet Sauvegarder Walter White.

🐰 Assurez-vous d’avoir créé un jeton API et de l’avoir défini comme variable d’environnement BENCHER_API_TOKEN avant de continuer !

Le Benchmarking Continu Relatif réalise une comparaison côte à côte de deux versions de votre code. Cela peut être utile dans des environnements CI/CD bruyants, où les ressources disponibles peuvent varier considérablement entre les exécutions. Dans cet exemple, nous comparerons les résultats d’exécution sur la branche main aux résultats d’exécution sur une branche fonctionnelle, justement nommée feature-branch. Comme chaque environnement CI est un peu différent, l’exemple suivant est davantage illustratif que pratique. Pour des exemples plus spécifiques, voir Benchmarking Continu dans GitHub Actions et Benchmarking Continu dans GitLab CI/CD.

Tout d’abord, nous devons basculer sur la branche main avec git dans CI :

Terminal window
git checkout main

Ensuite, nous avons besoin de lancer nos benchmarks sur la branche main dans CI :

Terminal window
bencher run \
--project save-walter-white-1234abcd \
--branch main \
--start-point-reset \
--testbed ci-runner \
--adapter json \
bencher mock
  1. Utilisez la sous-commande CLI bencher run pour exécuter vos benchmarks de la branche main. Voir un aperçu complet de la sous-commande CLI bencher run. (ex : bencher run)
  2. Définissez l’option --project à l’identifiant du Projet. Voir les détails des docs --project. (ex : --project save-walter-white-1234abcd)
  3. Définissez l’option --branch au nom de la Branche de base. Voir un aperçu complet des docs --branch. (ex : --branch main)
  4. Définissez l’indicateur --start-point-reset pour toujours réinitialiser la Branche de base. Cela garantira que toutes les données de benchmark proviennent de l’exécuteur CI actuel. Voir un aperçu complet des docs --start-point-reset. (ex : --start-point-reset)
  5. Définissez l’option --testbed au nom du Testbed de l’exécuteur CI. Voir les détails des docs --testbed. (ex : --testbed ci-runner)
  6. Définissez l’option --adapter au Format de Métrique Bencher JSON (json) généré par bencher mock. Voir un aperçu complet des adaptateurs de harnais de benchmark. (ex : --adapter json)
  7. Spécifiez les arguments de la commande de benchmark. Voir un aperçu complet de la commande de benchmark. (ex : bencher mock)

La première fois que cette commande est exécutée dans CI, elle créera la Branche main car elle n’existe pas encore. La nouvelle main n’aura pas de point de départ, de données existantes, ni de Seuils. Lors des exécutions subséquentes, l’ancien Head de la main sera remplacé, et un nouveau Head de la main sera créé sans point de départ, données existantes, ni Seuils.

Ensuite, nous devons basculer sur la branche feature-branch avec git dans CI :

Terminal window
git checkout feature-branch

Enfin, nous sommes prêts à exécuter nos benchmarks de feature-branch dans 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. Utilisez la sous-commande CLI bencher run pour exécuter vos benchmarks de feature-branch. Voir un aperçu complet de la sous-commande CLI bencher run. (ex : bencher run)
  2. Définissez l’option --project à l’identifiant du Projet. Voir les détails des docs --project. (ex : --project save-walter-white-1234abcd)
  3. Définissez l’option --branch au nom de la Branche fonctionnelle. Voir un aperçu complet des docs --branch. (ex : --branch feature-branch)
  4. Définissez le Point de Départ pour la Branche feature-branch :
    1. Définissez l’option --start-point au point de départ de la Branche fonctionnelle. Voir un aperçu complet des docs --start-point. (ex : --start-point main)
    2. Définissez l’indicateur --start-point-reset pour toujours réinitialiser la Branche au point de départ. Cela n’utilisera que les derniers résultats de benchmark relatifs. Voir un aperçu complet des docs --start-point-reset. (ex : --start-point-reset)
  5. Définissez l’option --testbed au nom du Testbed de l’exécuteur CI. Voir les détails des docs --testbed. (ex : --testbed ci-runner)
  6. Définissez le Seuil pour la Branche feature-branch, le Testbed ci-runner, et la Mesure latency :
    1. Définissez l’option --threshold-measure à la Mesure intégrée latency générée par bencher mock. Voir les détails des docs --threshold-measure. (ex : --threshold-measure latency)
    2. Définissez l’option --threshold-test à un pourcentage de base (percentage). Voir un aperçu complet des docs --threshold-test. (ex : --threshold-test percentage)
    3. Définissez l’option --threshold-upper-boundary à la Limite Supérieure de 0.25. Voir les détails des docs --threshold-upper-boundary. (ex : --threshold-upper-boundary 0.25)
    4. Définissez l’indicateur --thresholds-reset pour que seul le Seuil spécifié soit actif. Voir un aperçu complet des docs --thresholds-reset. (ex : --thresholds-reset)
  7. Définissez l’indicateur --err pour échouer à la commande si une Alarme est générée. Voir un aperçu complet des docs --err. (ex : --err)
  8. Définissez l’option --adapter au Format de Métrique Bencher JSON (json) généré par bencher mock. Voir un aperçu complet des adaptateurs de harnais de benchmark. (ex : --adapter json)
  9. Spécifiez les arguments de la commande de benchmark. Voir un aperçu complet de la commande de benchmark. (ex : bencher mock)

Chaque fois que cette commande est exécutée dans CI, elle compare les résultats de feature-branch uniquement avec les résultats les plus récents de main. Le Seuil spécifié est alors utilisé pour détecter les régressions de performance.

Détection de Point de Changement

La Détection de Point de Changement utilise un algorithme de détection de changement pour évaluer une grande fenêtre de résultats récents. Cela permet à l’algorithme d’ignorer les valeurs aberrantes comme du bruit et de produire moins de faux positifs. Même si la Détection de Point de Changement est considérée comme du benchmarking en continu, elle ne vous permet pas de détecter une régression de performance en CI. C’est-à-dire que vous ne pouvez pas détecter une régression de performance avant qu’une branche de fonctionnalité ne soit fusionnée. Cela est parfois appelé détection “hors bande”.

Par exemple, si vous avez un benchmark bench_my_critical_path, et qu’il avait les latences historiques suivantes : 5 ms, 6 ms, 5 ms, 5 ms, 7 ms.

Si le résultat du benchmark suivant était 11 ms, alors un seuil de Benchmarking Continu Statistique et l’algorithme de Détection de Point de Changement interpréteraient les choses très différemment. Il est probable que le seuil serait dépassé et qu’une alerte serait générée. Si cette exécution de benchmark était liée à une demande de tirage, la construction serait probablement définie pour échouer à cause de cette alerte. Cependant, l’algorithme de point de changement ne ferait rien… pour l’instant. Si lors de la prochaine exécution, les choses revenaient à 5 ms, alors il ne générerait probablement pas d’alerte. Inversement, si les exécutions suivantes résultaient en 10 ms et 12 ms, alors seulement l’algorithme de point de changement déclencherait une alerte.

Êtes-vous intéressé par l’utilisation de la Détection de Point de Changement avec Bencher ? Si oui, veuillez laisser un commentaire sur l’issue de suivi ou contactez-nous directement.



🐰 Félicitations ! Vous avez appris comment suivre les benchmarks dans l’Intégration Continue avec Bencher ! 🎉


Ajouter Bencher à GitHub Actions ➡

Ajouter Bencher à GitLab CI/CD ➡

🤖 Ce document a été automatiquement généré par OpenAI GPT-4. Il peut ne pas être précis et peut contenir des erreurs. Si vous trouvez des erreurs, veuillez ouvrir une issue sur GitHub.


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