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
cProfile
epstats
. - 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
numpy
o estensioni C per loop numerici intensivi.
Esercizi
- Valuta due implementazioni di Fibonacci con
timeit
. - Profila uno script di trasformazione dati con
cProfile
e ottimizza il punto critico. - Usa
line_profiler
su 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
.