Laufzeit messen mit timeit

Verwendung des timeit Modules

Um Laufzeit von Code in Python zu messen gibt es unter Anderem das Modul timeit. Im aktuellen Beitrag messen wir die Ausführungsgeschwindigkeit mehrerer mathematischer Funktionen.

Das Modul timeit kann sowohl in der Konsole, als auch in einem Skript verwendet werden. Im ersten Beispiel führen wir eine Berechnung in der Konsole durch. Nach Start der Python Shell geben wir folgenden Befehl ein:

python3 -m timeit "sum([x**2 for x in range(1,1001)])"

Nach dem Modulnamen timeit folgt ein String, der den zu messenden Code enthält. In unserem Fall berechnen wir alle Quadratzahlen von 1 bis 1000 und ermitteln deren Summe. Nach Ausführung erhalten wir folgende Ausgabe:

1000 loops, best of 3: 302 usec per loop

Unsere Berechnung wurde 1000 mal ausgeführt und anschließend wurde die schnellste Zeitmessung aus drei Wiederholungen ausgegeben. Über den Parameter -n und -r lassen sich die Parameter number und repeat verändern. Weitere Parameter sind hier beschrieben.

python3 -m timeit -n 1 -r 10 "sum([x**2 for x in range(1,1001)])"

Ausgabe:

1 loops, best of 10: 297 usec per loop

Somit können wir davon ausgehen, dass auf unserem System die gewünschte Berechnung circa 300 Mikrosekunden in Anspruch nimmt.

Als nächstes befassen wir uns mit der Verwendung von timeit in Skripten. Im ersten Schritt binden wir das Modul timeit ein. Anschließend implementieren wir die Funktion fakultaet(num). Diese berechnet die Fakultät einer Zahl und wir wollen sie mit der im math Modul vorhandenen Funktion factorial() vergleichen.

Aufgrund der hohen Zahlen bei der Berechnung von Fakultäten geben wir für unseren ersten Test nur die Anzahl der Stellen aus:

fakultaet(10000) hat 35660 Stellen

Um timeit innerhalb von Skripten zu verwenden, muss der zu messende Code als String übergeben werden. Wir erstellen eine Kopie unserer Funktion und definieren sie als String namens TEST_FAKULTAET. Nun können wir unseren Performance Vergleich durchführen:

Die Funktion timeit.timeit() verfügt über fünf Parameter. Die Wichtigsten sind stmt (Code der gemessen werden soll), setup (Code, der einmalig zu Beginn ausgeführt wird) und number (Anzahl der Wiederholungen der Ausführung des Codes). Wir übergeben nun unseren erstellten String der Messfunktion und setzen number auf 1. Im Fall der Messung von factorial() müssen wir via setup zuerst das math Modul einbinden.

Ausgabe:

0.02177235599992855
0.002770686000076239

Die Messung ergibt, dass unsere Implementierung nicht besonders geglückt ist. Die Funktion factorial() aus dem math Modul ist deutlich schneller in der Ausführung.

Anstatt timeit direkt auszuführen, können wir auch die Timer Klasse verwenden. Wir speichern die Auszuführenden Berechnungen in den Objekten TIME1 und TIME2. Anschließend führen wir timeit() und repeat() auf diese Objekte aus. Im ersten Fall legen wir die Anzahl an Schleifendurchläufen fest, im Zweiten definieren wir auch die Wiederholungen für die Zeitmessung.

Ausgabe:

0.02205854299972998
0.0028893759990751278
[0.024208838000049582, 0.02011976599897025, 0.020180663999781245]
[0.0027402919986343477, 0.002924312999311951, 0.0027616349998424994]

In den letzten beiden Zeilen erhalten wir jeweils drei Messergebnisse. Diese Anzahl kann mit einem anderen Wert für den Parameter repeat verändert werden. Da auf einem Computer zu jeder Zeit unterschiedliche Prozesse laufen, unterscheiden sich die Messergebnisse. Es lassen sich jedoch gute Schätzungen erreichen. Wer genauere Messungen benötigt, sollte sich mit dem Thema Profiling befassen.

Das komplette Beispiel herunterladen: python_timeit.zip

Über Anton Neururer 31 Artikel
Ich bin Programmierer und Blogger. Themen die mich besonders interessieren sind Python, C++ und Javascript. Des Weiteren befasse ich mich mit Fraktalen.

Hinterlasse jetzt einen Kommentar

Kommentar hinterlassen