| Nächste Überarbeitung | Vorhergehende Überarbeitung |
| modul:m323:learningunits:lu07:aufgaben:profiling [2026/09/09 11:18] – LU07.A11 - Den echten Hotspot finden (neu, D1A) admin | modul:m323:learningunits:lu07:aufgaben:profiling [2026/09/09 13:54] (aktuell) – Repo-Verlinkung korrigiert: nodisp im Footer statt Link im Text admin |
|---|
| |
| <code python> | <code python> |
| import random | GESPERRT = [f"user{i}" for i in range(5000)] |
| random.seed(1) | |
| | |
| gesperrt = [f"user{i}" for i in range(5000)] | |
| anfragen = [f" User{random.randrange(10000)} " for _ in range(3000)] | |
| |
| |
| |
| def ist_gesperrt(name): | def ist_gesperrt(name): |
| return name in gesperrt | return name in GESPERRT |
| | |
| | |
| def formatieren(treffer): | |
| return "\n".join(f"gesperrt: {t}" for t in treffer) | |
| |
| |
| return [n for n in namen if ist_gesperrt(normalisieren(n))] | return [n for n in namen if ist_gesperrt(normalisieren(n))] |
| </code> | </code> |
| | |
| | Die Anfragen kommen in unsauberer Schreibweise herein (''" User1234 "''), deshalb wird jede zuerst normalisiert. |
| |
| ==== Detaillierte Aufgabenstellung ==== | ==== Detaillierte Aufgabenstellung ==== |
| |
| - **Tippen Sie zuerst.** Notieren Sie schriftlich, welche der drei Funktionen Ihrer Meinung nach am meisten Zeit braucht - und warum. Erst danach messen. | - **Tippen Sie zuerst.** Notieren Sie schriftlich, welche der drei Funktionen Ihrer Meinung nach am meisten Zeit braucht - und warum. Erst danach messen. Dieser Schritt ist der Kern der Aufgabe. |
| - Profilen Sie den Aufruf: | - **Profilen:** ''python main.py'' führt die vorbereitete Funktion ''profil()'' aus. |
| <code python> | - Lesen Sie ''ncalls'', ''tottime'' und ''cumtime'' und bestimmen Sie den Hotspot. Den Hotspot suchen Sie in ''tottime'', nicht in ''cumtime'' - sonst steht immer die äusserste Funktion zuoberst. |
| import cProfile, pstats | - Ändern Sie **nur** den Hotspot. Messen Sie mit ''timeit'' vorher und nachher, prüfen Sie das Ergebnis mit ''assert''. |
| cProfile.run("pruefen(anfragen)", "profil.stats") | - Profilen Sie erneut. Was steht jetzt zuoberst, und wie gross ist die Gesamtlaufzeit noch? |
| pstats.Stats("profil.stats").sort_stats("cumulative").print_stats(8) | |
| </code> | |
| - Lesen Sie ''ncalls'', ''tottime'' und ''cumtime'' und bestimmen Sie den Hotspot. | |
| - Ändern Sie **nur** den Hotspot. Messen Sie mit ''timeit'' vorher und nachher und prüfen Sie das Ergebnis mit ''assert''. | |
| - Optimieren Sie anschliessend zusätzlich die Funktion, die Sie ursprünglich im Verdacht hatten. Messen Sie, was das bringt. | |
| |
| ==== Zu beantwortende Fragen ==== | ==== Regeln ==== |
| | |
| | <WRAP center round important 80%> |
| | ''normalisieren'' und ''ist_gesperrt'' bleiben als **benannte Funktionen** erhalten; zwei Tests prüfen das. Die naheliegende zweite Optimierung - alle Hilfsfunktionen in die Comprehension ziehen - bringt weniger als ein Prozent und kostet zwei einzeln testbare Funktionen. Das ist ein Refactoring in die falsche Richtung, verkauft als Optimierung. |
| | </WRAP> |
| | |
| | ==== Zu beantwortende Fragen (BEFUND.md) ==== |
| |
| * Warum wirkt ''normalisieren'' teuer, obwohl es das nicht ist? | * Warum wirkt ''normalisieren'' teuer, obwohl es das nicht ist? |
| * Was sagt ''ncalls'' über die Struktur des Programms aus? | * Was sagt ''ncalls'' über die Struktur des Programms aus? |
| * Was ist der Unterschied zwischen ''tottime'' und ''cumtime'' bei ''pruefen''? | * Was ist der Unterschied zwischen ''tottime'' und ''cumtime'' bei ''pruefen''? |
| * Wie viel Prozent der Gesamtzeit haben Sie mit der zweiten Optimierung noch gewonnen - und war der Aufwand gerechtfertigt? | * Wie viel Prozent der Gesamtzeit brächte die zweite Optimierung noch - und wäre der Aufwand gerechtfertigt? |
| | |
| | ==== Bewertung ==== |
| | |
| | ^ Teil ^ Punkte ^ |
| | | Tests (''main_test.py'') | 9 | |
| | | pylint (''main.py'') | 5 | |
| |
| ---- | ---- |
| | <nodisp>https://github.com/templates-python/m323-lu07-a11-profiling</nodisp> |
| {{tag>M323-LU07 M323-D1A}} | {{tag>M323-LU07 M323-D1A}} |
| [[https://creativecommons.org/licenses/by-nc-sa/4.0/ch/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] (c) Kevin Maurizi | [[https://creativecommons.org/licenses/by-nc-sa/4.0/ch/|{{https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png}}]] (c) Kevin Maurizi |
| |