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
- Suivre les résultats des benchmarks dans le temps pour créer une base de référence
- Utiliser cette base de référence avec des seuils statistiques pour créer une frontière statistique
- Comparer les nouveaux résultats à cette frontière statistique pour détecter les régressions de performance
- Évaluation continue relative des performances
- Exécuter les benchmarks pour le code de base actuel
- Passer à la nouvelle version du code
- Utiliser des seuils de pourcentage pour créer une frontière pour le code de base
- Exécuter les benchmarks pour la nouvelle version du code
- 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
- Exécuter occasionnellement les benchmarks pour les nouvelles versions du code
- Utiliser un algorithme de détection de point de changement pour détecter les régressions de performance
- 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 claimed.
🐰 Assurez-vous d’avoir créé un jeton API et de l’avoir défini comme variable d’environnement
BENCHER_API_TOKENavant 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 :
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- Utilisez la sous-commande CLI
bencher runpour exécuter les benchmarks de votre branchemain. Voir la sous-commande CLIbencher runpour un aperçu complet. (ex:bencher run) - Définissez l’option
--projectsur le slug du Projet. Voir la documentation--projectpour plus de détails. (ex:--project project-abc4567-wxyz123456789) - Définissez l’option
--branchsur le nom de la branche de base. Voir la documentation--branchpour un aperçu complet. (ex:--branch main) - Définissez l’option
--testbedsur le nom du Testbed du coureur CI. Voir la documentation--testbedpour plus de détails. (ex:--testbed ci-runner) - Définissez le Seuil pour la branche
main, le Testbedci-runneret la Mesurelatency:- Définissez l’option
--threshold-measuresur la Mesurelatencyintégrée générée parbencher mock. Voir la documentation--threshold-measurepour plus de détails. (ex:--threshold-measure latency) - Définissez l’option
--threshold-testsur un test t de Student (t_test). Voir la documentation--threshold-testpour un aperçu complet. (ex:--threshold-test t_test) - Définissez l’option
--threshold-max-sample-sizesur la taille d’échantillon maximale de64. Voir la documentation--threshold-max-sample-sizepour plus de détails. (ex:--threshold-max-sample-size 64) - Définissez l’option
--threshold-upper-boundarysur la Limite Supérieure de0.99. Voir la documentation--threshold-upper-boundarypour plus de détails. (ex:--threshold-upper-boundary 0.99) - Activez le drapeau
--thresholds-resetpour que seul le Seuil spécifié soit actif. Voir la documentation--thresholds-resetpour un aperçu complet. (ex:--thresholds-reset)
- Définissez l’option
- Activez le drapeau
--errpour que la commande échoue si une Alerte est générée. Voir la documentation--errpour un aperçu complet. (ex:--err) - Définissez l’option
--adaptersur Bencher Metric Format JSON (json) généré parbencher mock. Voir les adaptateurs de harnais de benchmark pour un aperçu complet. (ex:--adapter json) - 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 :
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- Utilisez la sous-commande CLI
bencher runpour exécuter les benchmarks de votre branchefeature-branch. Voir la sous-commande CLIbencher runpour un aperçu complet. (ex:bencher run) - Définissez l’option
--projectsur le slug du Projet. Voir la documentation--projectpour plus de détails. (ex:--project project-abc4567-wxyz123456789) - Définissez l’option
--branchsur le nom de la branche de fonctionnalité. Voir la documentation--branchpour un aperçu complet. (ex:--branch feature-branch) - Définissez le Point de Départ pour la branche
feature-branch:- Définissez l’option
--start-pointsur le point de départ de la branche de fonctionnalité. Voir la documentation--start-pointpour un aperçu complet. (ex:--start-point main) - Définissez l’option
--start-point-hashsur le hachagegitdu point de départ de la branche de fonctionnalité. Voir la documentation--start-point-hashpour un aperçu complet. (ex:--start-point-hash 32ae...dd8b) - Activez le drapeau
--start-point-clone-thresholdspour cloner les Seuils du point de départ. Voir la documentation--start-point-clone-thresholdspour un aperçu complet. (ex:--start-point-clone-thresholds) - Activez le drapeau
--start-point-resetpour 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-resetpour un aperçu complet. (ex:--start-point-reset)
- Définissez l’option
- Définissez l’option
--testbedsur le nom du Testbed. Voir la documentation--testedpour plus de détails. (ex:--testbed ci-runner) - Activez le drapeau
--errpour que la commande échoue si une Alerte est générée. Voir la documentation--errpour un aperçu complet. (ex:--err) - Définissez l’option
--adaptersur Bencher Metric Format JSON (json) généré parbencher mock. Voir les adaptateurs de harnais de benchmark pour un aperçu complet. (ex:--adapter json) - 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_TOKENavant 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 :
git checkout mainEnsuite, nous avons besoin de lancer nos benchmarks sur la branche main dans CI :
bencher run \--project project-abc4567-wxyz123456789 \--branch main \--start-point-reset \--testbed ci-runner \--adapter json \bencher mock- Utilisez la sous-commande CLI
bencher runpour exécuter vos benchmarks de la branchemain. Voir un aperçu complet de la sous-commande CLIbencher run. (ex :bencher run) - Définissez l’option
--projectà l’identifiant du Projet. Voir les détails des docs--project. (ex :--project project-abc4567-wxyz123456789) - Définissez l’option
--branchau nom de la Branche de base. Voir un aperçu complet des docs--branch. (ex :--branch main) - Définissez l’indicateur
--start-point-resetpour 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) - Définissez l’option
--testbedau nom du Testbed de l’exécuteur CI. Voir les détails des docs--testbed. (ex :--testbed ci-runner) - Définissez l’option
--adapterau Format de Métrique Bencher JSON (json) généré parbencher mock. Voir un aperçu complet des adaptateurs de harnais de benchmark. (ex :--adapter json) - 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 :
git checkout feature-branchEnfin, nous sommes prêts à exécuter nos benchmarks de feature-branch dans 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- Utilisez la sous-commande CLI
bencher runpour exécuter vos benchmarks defeature-branch. Voir un aperçu complet de la sous-commande CLIbencher run. (ex :bencher run) - Définissez l’option
--projectà l’identifiant du Projet. Voir les détails des docs--project. (ex :--project project-abc4567-wxyz123456789) - Définissez l’option
--branchau nom de la Branche fonctionnelle. Voir un aperçu complet des docs--branch. (ex :--branch feature-branch) - Définissez le Point de Départ pour la Branche
feature-branch:- Définissez l’option
--start-pointau point de départ de la Branche fonctionnelle. Voir un aperçu complet des docs--start-point. (ex :--start-point main) - Définissez l’indicateur
--start-point-resetpour 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)
- Définissez l’option
- Définissez l’option
--testbedau nom du Testbed de l’exécuteur CI. Voir les détails des docs--testbed. (ex :--testbed ci-runner) - Définissez le Seuil pour la Branche
feature-branch, le Testbedci-runner, et la Mesurelatency:- Définissez l’option
--threshold-measureà la Mesure intégréelatencygénérée parbencher mock. Voir les détails des docs--threshold-measure. (ex :--threshold-measure latency) - Définissez l’option
--threshold-testà un pourcentage de base (percentage). Voir un aperçu complet des docs--threshold-test. (ex :--threshold-test percentage) - Définissez l’option
--threshold-upper-boundaryà la Limite Supérieure de0.25. Voir les détails des docs--threshold-upper-boundary. (ex :--threshold-upper-boundary 0.25) - Définissez l’indicateur
--thresholds-resetpour que seul le Seuil spécifié soit actif. Voir un aperçu complet des docs--thresholds-reset. (ex :--thresholds-reset)
- Définissez l’option
- Définissez l’indicateur
--errpour échouer à la commande si une Alarme est générée. Voir un aperçu complet des docs--err. (ex :--err) - Définissez l’option
--adapterau Format de Métrique Bencher JSON (json) généré parbencher mock. Voir un aperçu complet des adaptateurs de harnais de benchmark. (ex :--adapter json) - 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 ! 🎉