Capitolo 19: Profiling & Ottimizzazione delle Prestazioni
Misura le prestazioni del tuo codice, individua i punti critici e applica ottimizzazioni con strumenti built-in e di terze parti.
Scaricachapter19.py
Obiettivi
- Misurare il tempo di esecuzione con
timeit. - Profilare funzioni con
cProfileepstats. - Analizzare i tempi linea per linea con
line_profiler. - Analizzare l’uso di memoria con
memory_profiler. - Applicare semplici ottimizzazioni a livello di codice.
1. Misurare il Tempo con timeit
Usa timeit per micro-benchmark:
import timeit
# one-liner
print(timeit.timeit("sum(range(1000))", number=10000))
# con Timer
timer = timeit.Timer("x*x for x in range(1000)")
print(timer.timeit(number=5000))
2. Profiling con cProfile
Raccogli statistiche a livello di funzione:
import cProfile, pstats
def work():
total = 0
for i in range(100000):
total += i
return total
prof = cProfile.Profile()
prof.enable()
work()
prof.disable()
stats = pstats.Stats(prof)
stats.sort_stats("cumtime").print_stats(10)
3. Profiling Linea per Linea
Installa con pip install line_profiler e decora la funzione:
@profile
def compute():
total = 0
for i in range(100000):
total += i*i
return total
if __name__ == "__main__":
compute()
Avvia con kernprof -l -v chapter19.py per i tempi linea per linea.
4. Memory Profiling
Installa con pip install memory_profiler e usa:
from memory_profiler import profile
@profile
def load_data():
data = [i for i in range(1000000)]
return data
if __name__ == "__main__":
load_data()
Avvia con python -m memory_profiler chapter19.py.
5. Consigli di Ottimizzazione
- Preferisci built-in come
sum(),map()e comprensioni anziché loop manuali. - Cache delle chiamate costose con
functools.lru_cache. - Usa variabili locali nei loop per velocità.
- Evita lookup globali assegnando funzioni frequentemente usate a variabili locali.
- Valuta
numpyo estensioni C per loop numerici intensivi.
Esercizi
- Valuta due implementazioni di Fibonacci con
timeit. - Profila uno script di trasformazione dati con
cProfilee ottimizza il punto critico. - Usa
line_profilersu una funzione con loop annidati e velocizza la linea più critica. - Misura l’uso di memoria di un’ampia lista vs espressione generatrice con
memory_profiler.