Benchmarking SciPy mit airspeed velocity#

Dieses Dokument führt in das Benchmarking ein, einschließlich der Online-Überprüfung von SciPy-Benchmark-Testergebnissen, dem Schreiben eines Benchmark-Tests und dessen lokaler Ausführung. Für eine Video-Durchlaufanleitung zum Schreiben eines Tests und dessen lokaler Ausführung siehe Benchmarking SciPy.

Wie in der Dokumentation zu airspeed velocity (asv) beschrieben

Airspeed velocity (asv) ist ein Werkzeug zum Benchmarking von Python-Paketen über ihre gesamte Lebensdauer hinweg. Laufzeit, Speicherverbrauch und sogar benutzerdefinierte Werte können verfolgt werden. Die Ergebnisse werden in einem interaktiven Web-Frontend angezeigt, das nur einen grundlegenden statischen Webserver zum Hosten benötigt.

Um zu sehen, was das bedeutet, werfen Sie einen Blick auf airspeed velocity eines unbeladenen Scipy. Jedes Diagramm fasst die Ausführungszeit eines bestimmten Tests über den Commit-Verlauf des Projekts zusammen; das heißt, mit jedem zusammengeführten Commit wird der Benchmark-Test ausgeführt, seine Ausführungszeit gemessen und die verstrichene Zeit geplottet. Neben der Verfolgung der Leistung des Codes, die ein Commit beeinflussen soll, ist die Ausführung aller Benchmarks für jeden Commit hilfreich, um unbeabsichtigte Regressionen zu identifizieren: signifikante Erhöhungen der Ausführungszeit eines oder mehrerer Benchmark-Tests. Da SciPy ein Netz aus miteinander verbundenem Code ist, sind die Auswirkungen einer kleinen Änderung für einen Mitwirkenden möglicherweise nicht sofort ersichtlich. Daher erleichtert diese Benchmark-Suite das Erkennen von Regressionen und das Identifizieren des Commits, der sie verursacht hat. Wenn Sie ein wesentliches neues Feature beisteuern - oder ein Feature bemerken, das noch keinen Benchmark-Test hat - ziehen Sie bitte in Erwägung, Benchmarks zu schreiben.

Schreiben von Benchmarks#

Der Abschnitt Schreiben von Benchmarks in der Dokumentation zu airspeed velocity ist der definitive Leitfaden zum Schreiben von Benchmarks. Bitte beachten Sie auch die README-Datei für SciPy-Benchmarks.

Um zu sehen, wie Benchmarks geschrieben werden, werfen Sie einen Blick auf scipy/benchmarks/benchmarks/optimize_linprog.py. Jede Unterklasse von Benchmark definiert einen Benchmark-Test. Zum Beispiel definiert die Klasse KleeMinty einen Benchmark-Test, der auf dem Klee-Minty-Hyperwürfelproblem basiert, einem tückischen Test für den Simplex-Algorithmus der linearen Programmierung. Die Klasse hat vier Teile

  • setup bereitet den Benchmark für die Ausführung vor. Die Ausführungszeit dieser Funktion wird nicht in die Benchmark-Ergebnisse einbezogen, daher ist dies ein guter Ort, um alle Variablen einzurichten, die das Problem definieren. Im KleeMinty-Beispiel werden dabei die Arrays c, A_ub und b_ub generiert, die einem Klee-Minty-Hyperwürfel in dims Dimensionen entsprechen, und als Instanzvariablen gespeichert.

  • time_klee_minty führt tatsächlich den Benchmark-Test aus. Diese Funktion wird ausgeführt, nachdem ein KleeMinty-Objekt instanziiert und setup ausgeführt wurde, sodass sie die das Problem definierenden Arrays aus self abruft. Beachten Sie, dass das Präfix time im Funktionsnamen angibt, dass die Ausführungszeit dieser Funktion zusammen mit den Benchmark-Ergebnissen gezählt werden soll.

  • params ist eine Liste von Listen, die Parameter des Tests definieren. Benchmarks werden für alle möglichen Kombinationen dieser Parameter ausgeführt. Zum Beispiel wird beim ersten Ausführen des Benchmarks das erste Element von methods (simplex) an setup und time_klee_minty als erstes Argument, meth, übergeben, und das erste Element von [3, 6, 9] (3) wird an setup und time_klee_minty als zweites Argument, dims, übergeben. Beim nächsten Ausführen des Benchmarks werden setup und time_klee_minty mit revised simplex und 6 als Argumenten übergeben, und so weiter, bis alle Parameterkombinationen verwendet wurden.

  • param_names ist eine Liste von menschenlesbaren Namen für jedes Element der params-Liste. Diese werden zur Darstellung der Ergebnisse verwendet.

Die Ergebnisse dieses Benchmarks der letzten Jahre sind durch Klicken auf den Link KleeMinty.time_klee_minty bei airspeed velocity eines unbeladenen Scipy verfügbar. Beachten Sie, dass jede Spur des Diagramms einer Kombination von Benchmark-Parametern und Umgebungseinstellungen (z. B. der Cython-Version) entspricht und dass die Sichtbarkeit der Spuren über das Bedienfeld auf der linken Seite umgeschaltet werden kann.

Benchmarks lokal ausführen#

Stellen Sie vor Beginn sicher, dass airspeed velocity installiert ist.

Nachdem Sie neue Benchmarks beigesteuert haben, sollten Sie diese lokal testen, bevor Sie einen Pull-Request einreichen.

Um alle Benchmarks auszuführen, navigieren Sie an der Kommandozeile zum Stammverzeichnis von SciPy und führen Sie Folgendes aus

python dev.py bench

wobei bench die Benchmark-Suite anstelle der Test-Suite aktiviert. Dies baut SciPy und führt die Benchmarks aus. (Hinweis: Dies kann eine Weile dauern. Benchmarks dauern oft länger als Unit-Tests, und jeder Benchmark wird mehrmals ausgeführt, um die Verteilung der Ausführungszeiten zu messen.)

Um Benchmarks aus einem bestimmten Benchmark-Modul, z. B. optimize_linprog.py, auszuführen, hängen Sie einfach den Dateinamen ohne Erweiterung an

python dev.py bench -t optimize_linprog

Um einen Benchmark auszuführen, der in einer Klasse definiert ist, wie z. B. KleeMinty aus optimize_linprog.py

python dev.py bench -t optimize_linprog.KleeMinty

Um Benchmark-Ergebnisse zwischen dem aktiven Branch und einem anderen, z. B. main, zu vergleichen

python dev.py bench --compare main  # select again by `-t optimize_linprog`

Alle obigen Befehle zeigen die Ergebnisse als Klartext in der Konsole an, und die Ergebnisse werden nicht zum Vergleich mit zukünftigen Commits gespeichert. Für mehr Kontrolle, eine grafische Ansicht und um Ergebnisse für zukünftige Vergleiche speichern zu lassen, können Sie den asv-Befehl direkt verwenden.

Um ihn zu verwenden, navigieren Sie in der Konsole zu scipy/benchmarks und führen Sie dann Folgendes aus

asv run

Dieser Befehl führt die gesamte Benchmark-Suite aus und speichert die Ergebnisse für den Vergleich mit zukünftigen Commits.

Um nur einen einzigen Benchmark auszuführen, wie z. B. KleeMinty aus optimize_linprog.py

asv run --bench optimize_linprog.KleeMinty

Eine großartige Funktion von asv ist, dass es einen Benchmark nicht nur für den aktuellen Commit, sondern für jeden Commit in einem Bereich automatisch ausführen kann. linprog method='interior-point' wurde mit dem Commit 7fa17f2369e0e5ad055b23cc1a5ee079f9e8ca32 in SciPy übernommen, lassen Sie uns also den KleeMinty-Benchmark für 10 Commits zwischen damals und heute ausführen, um seine Leistung im Laufe der Zeit zu verfolgen

asv run --bench optimize_linprog.KleeMinty --steps 10 7fa17f..

Hinweis

Dies wird eine Weile dauern, da SciPy für jeden Commit neu kompiliert werden muss! Um den Erstellungsprozess von Benchmarks zu beschleunigen, können Sie ccache und f90cache installieren. Die Benchmark-Suite erkennt sie automatisch, wenn sie in den Verzeichnissen /usr/lib und /usr/local/lib installiert sind. Andernfalls müssen Sie sie zur Umgebungsvariable PATH hinzufügen.

Für weitere Informationen zur Angabe von Commit-Bereichen siehe die git revisions-Dokumentation.

Um die Ergebnisse zu "veröffentlichen" (vorzubereiten, damit sie angezeigt werden können) und sie in einer interaktiven Konsole zu "vorschau"en

asv publish
asv preview

ASV wird berichten, dass es einen Server ausführt. Mit einem beliebigen Browser können Sie die Ergebnisse überprüfen, indem Sie zu http://127.0.0.1:8080 (lokaler Rechner, Port 8080) navigieren.

Für viel mehr Informationen zu den asv-Befehlen siehe die Befehle-Dokumentation von airspeed velocity. (Tipp: Schauen Sie sich den Befehl asv find und die Optionen --quick, --skip-existing-commits und --profile für asv run an.)