Wie man Benchmarks in CI mit Bencher verfolgt
Die meisten Benchmark-Ergebnisse sind flüchtig. Sie verschwinden, sobald Ihr Terminal seine Scrollback-Grenze erreicht. Einige Benchmark-Frameworks erlauben es Ihnen, Ergebnisse zu zwischenspeichern, aber die meisten tun dies nur lokal. Bencher ermöglicht es Ihnen, Ihre Benchmarks sowohl von lokalen als auch von CI-Läufen zu verfolgen und die Ergebnisse zu vergleichen, während Sie weiterhin Ihr bevorzugtes Benchmark-Framework verwenden.
Es gibt drei beliebte Methoden, um Benchmark-Ergebnisse beim Continuous Benchmarking zu vergleichen, also beim Benchmarking in der CI:
- Statistisches Continuous Benchmarking
- Verfolgen Sie die Benchmark-Ergebnisse im Laufe der Zeit, um eine Basislinie zu erstellen
- Verwenden Sie diese Basislinie zusammen mit Statistischen Schwellenwerten, um eine statistische Grenze zu erstellen
- Vergleichen Sie die neuen Ergebnisse mit dieser statistischen Grenze, um Leistungsregressionen zu erkennen
- Relatives Continuous Benchmarking
- Führen Sie die Benchmarks für den aktuellen Basisliniencode aus
- Wechseln Sie zur neuen Version des Codes
- Verwenden Sie Prozentuale Schwellenwerte, um eine Grenze für den Basisliniencode zu erstellen
- Führen Sie die Benchmarks für die neue Version des Codes aus
- Vergleichen Sie die Ergebnisse der neuen Version des Codes mit den Ergebnissen des Basisliniencodes, um Leistungsregressionen zu erkennen
- Change Point Detection
- Führen Sie gelegentlich die Benchmarks für neue Versionen des Codes aus
- Verwenden Sie einen Change-Point-Detection-Algorithmus, um Leistungsregressionen zu erkennen
- Führen Sie eine Bisektion durch, um den Commit zu finden, der die Leistungsregression eingeführt hat
Statistisches Kontinuierliches Benchmarking
Anknüpfend an die Tutorials Schnellstart und Docker Selbstgehostet, fügen wir statistisches kontinuierliches Benchmarking zu unserem Save Walter White
Projekt hinzu.
🐰 Stellen Sie sicher, dass Sie einen API-Token erstellt und als die Umgebungsvariable
BENCHER_API_TOKEN
gesetzt haben, bevor Sie fortfahren!
Nun sind wir bereit, unsere Benchmarks in CI auszuführen. Da jede CI-Umgebung ein wenig anders ist, soll das folgende Beispiel eher veranschaulichend als praktisch sein. Für spezifischere Beispiele siehe Kontinuierliches Benchmarking in GitHub Actions und Kontinuierliches Benchmarking in GitLab CI/CD.
Zuerst müssen wir eine historische Basis für unseren main
Branch erstellen und pflegen, indem wir jede Änderung in CI benchmarken:
- Verwenden Sie den
bencher run
CLI-Unterbefehl, um Ihre Benchmarks für denmain
Branch auszuführen. Siehe denbencher run
CLI-Unterbefehl für eine vollständige Übersicht. (z.B.:bencher run
) - Setzen Sie die
--project
Option auf den Projektslug. Siehe die--project
Dokumentation für mehr Details. (z.B.:--project save-walter-white-1234abcd
) - Setzen Sie die
--branch
Option auf den Basis-Branch-Namen. Siehe die--branch
Dokumentation für eine vollständige Übersicht. (z.B.:--branch main
) - Setzen Sie die
--testbed
Option auf den Namen des CI-Runner Testbeds. Siehe die--testbed
Dokumentation für mehr Details. (z.B.:--testbed ci-runner
) - Setzen Sie den Schwellenwert für den
main
Branch, dasci-runner
Testbed und daslatency
Maß:- Setzen Sie die
--threshold-measure
Option auf das eingebautelatency
Maß, das vonbencher mock
generiert wird. Siehe die--threshold-measure
Dokumentation für mehr Details. (z.B.:--threshold-measure latency
) - Setzen Sie die
--threshold-test
Option auf einen Student’s t-Test (t_test
). Siehe die--threshold-test
Dokumentation für eine vollständige Übersicht. (z.B.:--threshold-test t_test
) - Setzen Sie die
--threshold-max-sample-size
Option auf die maximale Stichprobengröße von64
. Siehe die--threshold-max-sample-size
Dokumentation für mehr Details. (z.B.:--threshold-max-sample-size 64
) - Setzen Sie die
--threshold-upper-boundary
Option auf die obere Grenze von0.99
. Siehe die--threshold-upper-boundary
Dokumentation für mehr Details. (z.B.:--threshold-upper-boundary 0.99
) - Setzen Sie das
--thresholds-reset
Flag, sodass nur der angegebene Schwellenwert aktiv ist. Siehe die--thresholds-reset
Dokumentation für eine vollständige Übersicht. (z.B.:--thresholds-reset
)
- Setzen Sie die
- Setzen Sie das
--err
Flag, um den Befehl fehlschlagen zu lassen, wenn ein Alarm generiert wird. Siehe die--err
Dokumentation für eine vollständige Übersicht. (z.B.:--err
) - Setzen Sie die
--adapter
Option auf Bencher Metric Format JSON (json
), das vonbencher mock
generiert wird. Siehe Benchmark-Harness-Adapter für eine vollständige Übersicht. (z.B.:--adapter json
) - Geben Sie die Benchmark-Befehlsargumente an.
Siehe Benchmark-Befehl für eine vollständige Übersicht. (z.B.:
bencher mock
)
Das erste Mal, wenn dieser Befehl in CI ausgeführt wird,
erstellt er den main
Branch, falls dieser noch nicht existiert.
Der neue main
wird nicht über einen Startpunkt oder vorhandene Daten verfügen.
Ein Schwellenwert wird für den main
Branch, das ci-runner
Testbed und das latency
Maß erstellt.
Bei nachfolgenden Ausführungen werden dem main
Branch neue Daten hinzugefügt.
Der angegebene Schwellenwert wird dann verwendet, um Leistungsregressionen zu erkennen.
Jetzt sind wir bereit, Leistungsregressionen in CI zu erkennen.
So würden wir die Leistung eines neuen Feature-Branchs in CI verfolgen, passend benannt feature-branch
:
- Verwenden Sie den
bencher run
CLI-Unterbefehl, um Ihre Benchmarks für denfeature-branch
Branch auszuführen. Siehe denbencher run
CLI-Unterbefehl für eine vollständige Übersicht. (z.B.:bencher run
) - Setzen Sie die
--project
Option auf den Projektslug. Siehe die--project
Dokumentation für mehr Details. (z.B.:--project save-walter-white-1234abcd
) - Setzen Sie die
--branch
Option auf den Feature-Branch-Namen. Siehe die--branch
Dokumentation für eine vollständige Übersicht. (z.B.:--branch feature-branch
) - Setzen Sie den Startpunkt für den
feature-branch
Branch:- Setzen Sie die
--start-point
Option auf den Startpunkt des Feature-Branches. Siehe die--start-point
Dokumentation für eine vollständige Übersicht. (z.B.:--start-point main
) - Setzen Sie die
--start-point-hash
Option auf den Git-Hash des Startpunkts des Feature-Branches. Siehe die--start-point-hash
Dokumentation für eine vollständige Übersicht. (z.B.:--start-point-hash 32ae...dd8b
) - Setzen Sie das
--start-point-clone-thresholds
Flag, um die Schwellenwerte vom Startpunkt zu klonen. Siehe die--start-point-clone-thresholds
Dokumentation für eine vollständige Übersicht. (z.B.:--start-point-clone-thresholds
) - Setzen Sie das
--start-point-reset
Flag, um den Branch immer auf den Startpunkt zurückzusetzen. Dies verhindert das Abdriften von Benchmark-Daten. Siehe die--start-point-reset
Dokumentation für eine vollständige Übersicht. (z.B.:--start-point-reset
)
- Setzen Sie die
- Setzen Sie die
--testbed
Option auf den Namen des Testbeds. Siehe die--tested
Dokumentation für mehr Details. (z.B.:--testbed ci-runner
) - Setzen Sie das
--err
Flag, um den Befehl fehlschlagen zu lassen, wenn ein Alarm generiert wird. Siehe die--err
Dokumentation für eine vollständige Übersicht. (z.B.:--err
) - Setzen Sie die
--adapter
Option auf Bencher Metric Format JSON (json
), das vonbencher mock
generiert wird. Siehe Benchmark-Harness-Adapter für eine vollständige Übersicht. (z.B.:--adapter json
) - Geben Sie die Benchmark-Befehlsargumente an.
Siehe Benchmark-Befehl für eine vollständige Übersicht. (z.B.:
bencher mock
)
Das erste Mal, wenn dieser Befehl in CI ausgeführt wird,
wird Bencher den feature-branch
Branch erstellen, da er noch nicht existiert.
Der neue feature-branch
wird den main
Branch
bei Hash 32aea434d751648726097ed3ac760b57107edd8b
als seinen Startpunkt verwenden.
Das bedeutet, dass feature-branch
eine Kopie aller Daten und Schwellenwerte vom main
Branch haben wird, um die Ergebnisse von bencher mock
damit zu vergleichen.
Bei allen nachfolgenden Ausführungen wird Bencher den feature-branch
Branch auf den Startpunkt zurücksetzen
und die Daten und Schwellenwerte des main
Branch verwenden, um Leistungsregressionen zu erkennen.
Relative Continuous Benchmarking
Anknüpfend an unsere bisherigen Fortschritte in den
Quick Start und Docker Self-Hosted Tutorials,
fügen wir Relatives Continuous Benchmarking zu unserem Save Walter White
Projekt hinzu.
🐰 Stellen Sie sicher, dass Sie einen API-Token erstellt und als
BENCHER_API_TOKEN
Umgebungsvariable gesetzt haben bevor Sie fortfahren!
Relatives Continuous Benchmarking führt einen direkten Vergleich zwischen zwei Versionen Ihres Codes durch.
Dies kann nützlich sein, wenn man mit lauten CI/CD-Umgebungen zu tun hat,
bei denen die verfügbaren Ressourcen zwischen den Läufen stark variieren können.
In diesem Beispiel werden wir die Ergebnisse vom Laufen im main
Branch
mit den Ergebnissen aus einem feature Branch, treffend als feature-branch
benannt, vergleichen.
Da jede CI-Umgebung ein wenig anders ist,
soll dieses Beispiel mehr veranschaulichend als praktisch sein.
Für spezifischere Beispiele, siehe Continuous Benchmarking in GitHub Actions
und Continuous Benchmarking in GitLab CI/CD.
Zuerst müssen wir den main
Branch mit git
in CI auschecken:
Dann müssen wir unsere Benchmarks im main
Branch in CI ausführen:
- Verwenden Sie den
bencher run
CLI-Unterbefehl, um Ihremain
Branch Benchmarks auszuführen. Siehe denbencher run
CLI-Unterbefehl für eine vollständige Übersicht. (z.B.:bencher run
) - Setzen Sie die
--project
Option auf das Projektslug. Siehe die--project
Dokus für weitere Details. (z.B.:--project save-walter-white-1234abcd
) - Setzen Sie die
--branch
Option auf den Basisbranch-Namen. Siehe die--branch
Dokus für eine vollständige Übersicht. (z.B.:--branch main
) - Setzen Sie das
--start-point-reset
Flag, um den Basisbranch immer zurückzusetzen. Dies stellt sicher, dass alle Benchmark-Daten vom aktuellen CI-Runner stammen. Siehe die--start-point-reset
Dokus für eine vollständige Übersicht. (z.B.:--start-point-reset
) - Setzen Sie die
--testbed
Option auf den Namen des CI-Runner-Testbeds. Siehe die--testbed
Dokus für weitere Details. (z.B.:--testbed ci-runner
) - Setzen Sie die
--adapter
Option auf Bencher Metric Format JSON (json
), das vonbencher mock
generiert wird. Siehe benchmark harness adapters für eine vollständige Übersicht. (z.B.:--adapter json
) - Geben Sie die Argumente des Benchmark-Befehls an.
Siehe benchmark command für eine vollständige Übersicht.
(z.B.:
bencher mock
)
Beim ersten Mal, wenn dieser Befehl in CI ausgeführt wird,
wird der main
Branch erstellt, da er noch nicht existiert.
Der neue main
wird nicht über einen Startpunkt, vorhandene Daten oder Thresholds verfügen.
Bei nachfolgenden Läufen wird der alte main
Head ersetzt
und ein neuer main
Head wird erstellt, ohne einen Startpunkt, vorhandene Daten oder Thresholds.
Als nächstes müssen wir den feature-branch
Branch mit git
in CI auschecken:
Schließlich sind wir bereit, unsere feature-branch
Benchmarks in CI auszuführen:
- Verwenden Sie den
bencher run
CLI-Unterbefehl, um Ihrefeature-branch
Benchmarks auszuführen. Siehe denbencher run
CLI-Unterbefehl für eine vollständige Übersicht. (z.B.:bencher run
) - Setzen Sie die
--project
Option auf das Projektslug. Siehe die--project
Dokus für weitere Details. (z.B.:--project save-walter-white-1234abcd
) - Setzen Sie die
--branch
Option auf den Featurebranch-Namen. Siehe die--branch
Dokus für eine vollständige Übersicht. (z.B.:--branch feature-branch
) - Setzen Sie den Startpunkt für den
feature-branch
Branch:- Setzen Sie die
--start-point
Option auf den Startpunkt des Featurebranches. Siehe die--start-point
Dokus für eine vollständige Übersicht. (z.B.:--start-point main
) - Setzen Sie das
--start-point-reset
Flag, um den Branch immer auf den Startpunkt zurückzusetzen. Dabei werden nur die neuesten relativen Benchmark-Ergebnisse verwendet. Siehe die--start-point-reset
Dokus für eine vollständige Übersicht. (z.B.:--start-point-reset
)
- Setzen Sie die
- Setzen Sie die
--testbed
Option auf den Namen des CI-Runner-Testbeds. Siehe die--testbed
Dokus für weitere Details. (z.B.:--testbed ci-runner
) - Setzen Sie die Schwelle für den
feature-branch
Branch,ci-runner
Testbed undlatency
Measure:- Setzen Sie die
--threshold-measure
Option auf das eingebautelatency
Measure, das vonbencher mock
generiert wird. Siehe die--threshold-measure
Dokus für weitere Details. (z.B.:--threshold-measure latency
) - Setzen Sie die
--threshold-test
Option auf einen einfachen Prozentsatz (percentage
). Siehe die--threshold-test
Dokus für eine vollständige Übersicht. (z.B.:--threshold-test percentage
) - Setzen Sie die
--threshold-upper-boundary
Option auf die Obergrenze von0.25
. Siehe die--threshold-upper-boundary
Dokus für weitere Details. (z.B.:--threshold-upper-boundary 0.25
) - Setzen Sie das
--thresholds-reset
Flag, so dass nur die angegebene Schwelle aktiv ist. Siehe die--thresholds-reset
Dokus für eine vollständige Übersicht. (z.B.:--thresholds-reset
)
- Setzen Sie die
- Setzen Sie das
--err
Flag, um den Befehl zu beenden, falls ein Alert erzeugt wird. Siehe die--err
Dokus für eine vollständige Übersicht. (z.B.:--err
) - Setzen Sie die
--adapter
Option auf Bencher Metric Format JSON (json
), das vonbencher mock
generiert wird. Siehe benchmark harness adapters für eine vollständige Übersicht. (z.B.:--adapter json
) - Geben Sie die Argumente des Benchmark-Befehls an.
Siehe benchmark command für eine vollständige Übersicht.
(z.B.:
bencher mock
)
Jedes Mal, wenn dieser Befehl in CI ausgeführt wird,
vergleicht er die Ergebnisse des feature-branch
nur mit den neuesten Ergebnissen aus main
.
Die angegebene Schwelle wird dann verwendet, um Leistungsregressionen zu erkennen.
Change Point Detection
Change Point Detection verwendet einen Change Point Algorithmus, um ein großes Fenster aktueller Ergebnisse auszuwerten. Dies ermöglicht es dem Algorithmus, Ausreißer als Rauschen zu ignorieren und weniger Fehlalarme zu erzeugen. Obwohl Change Point Detection als [kontinuierliches Benchmarking][continuous benchmarking] betrachtet wird, erlaubt es nicht, Leistungsregressionen in CI zu erkennen. Das heißt, Sie können eine Leistungsregression nicht erkennen, bevor ein Feature-Branch zusammengeführt wird. Dies wird manchmal als “Out-of-Band”-Erkennung bezeichnet.
Zum Beispiel, wenn Sie einen Benchmark bench_my_critical_path
haben,
und dieser hatte folgende historische Latenzen: 5 ms
, 6 ms
, 5 ms
, 5ms
, 7ms
.
Wenn das nächste Benchmark-Ergebnis 11 ms
wäre, dann würden ein Schwellenwert für Statistisches Kontinuierliches Benchmarking
und der Change Point Detection Algorithmus die Dinge sehr unterschiedlich interpretieren.
Der Schwellenwert würde wahrscheinlich überschritten und ein Alarm würde generiert werden.
Wenn dieser Benchmark-Lauf mit einem Pull-Request verbunden wäre,
würde das Build wahrscheinlich aufgrund dieses Alarms fehlschlagen.
Der Change Point Algorithmus würde jedoch noch nichts unternehmen.
Wenn beim nächsten Lauf die Werte wieder auf 5 ms
fallen würden, würde wahrscheinlich kein Alarm generiert werden.
Umgekehrt, wenn der nächste Lauf oder zwei 10 ms
und 12 ms
ergeben würden,
würde der Change Point Algorithmus erst dann einen Alarm auslösen.
Haben Sie Interesse an der Verwendung von Change Point Detection mit Bencher? Falls ja, hinterlassen Sie bitte einen Kommentar im Tracking Issue oder kontaktieren Sie uns direkt.
🐰 Glückwunsch! Sie haben gelernt, wie man Benchmarks in CI mit Bencher verfolgt! 🎉