LU07.L08 - Vorgegebene Massnahmen umsetzen
Ergebnisse
Gemessen mit min(timeit.repeat(…, number=1, repeat=5)) auf einem Notebook, Python 3.12. Ihre absoluten Zahlen werden abweichen - die Grössenordnung der Faktoren nicht.
| Massnahme | vorher | nachher | Faktor | Begründung |
|---|---|---|---|---|
| 1 list → set | 0.107 s | 0.000068 s | ~1500 | in auf einer Liste prüft im Schnitt die halbe Liste (O(n)), das Set berechnet einen Hash (O(1)) |
| 2 Schleife → dict-Index | 0.0585 s | 0.00028 s | ~200 | Statt 2000 × 2000 Vergleichen (O(n²)) wird der Index einmal gebaut und dann direkt zugegriffen (O(n)) |
| 3 Memoization | 0.0899 s | 0.0000003 s | sehr gross | Ohne Cache berechnet der Aufrufbaum dieselben Teilprobleme tausendfach, mit Cache jedes genau einmal |
| 4 Arbeit aus der Schleife | 0.0877 s | 0.00025 s | ~350 | sorted lief 2000-mal mit identischer Eingabe und identischem Ergebnis |
Code
# 1 gesperrt = {f"user{i}" for i in range(10000)} # geschweifte statt eckige Klammern # 2 def zuordnen(bestellungen, kunden): index = {k["id"]: k for k in kunden} return [(index[b["kunde_id"]]["name"], b["betrag"]) for b in bestellungen] # 3 from functools import cache @cache def fibonacci(n): return n if n < 2 else fibonacci(n - 1) + fibonacci(n - 2) # 4 def top_drei_pro_kunde(kunden, produkte): top = [p["name"] for p in sorted(produkte, key=lambda p: p["preis"])[:3]] return {k["name"]: list(top) for k in kunden}
Fallen in dieser Aufgabe
- Massnahme 2: Die Vorher-Version behält die Reihenfolge der Bestellungen. Die Index-Version auch - aber nur, weil über
bestellungeniteriert wird. Wer überkundeniteriert, bekommt eine andere Reihenfolge und damit ein anderes Ergebnis. - Massnahme 3:
@cachefunktioniert nur bei pure functions mit hashbaren Argumenten. Eine Liste als Argument wirftTypeError: unhashable type. - Massnahme 4:
list(top)statttop- sonst teilen sich alle 2000 Kunden dieselbe Liste. Solange niemand sie verändert, fällt das nicht auf; sobald doch, ändern sich alle Einträge gleichzeitig. Das ist der Referenz-Effekt aus LU02d. - Ohne
assertist keine Messung gültig. Eine schnellere Funktion mit anderem Ergebnis ist keine Optimierung, sondern ein Bug.
