-
Introducere în optimizarea performanței
- Importanța optimizării performanței în dezvoltarea software
- Identificarea bottleneck-urilor și alocarea resurselor
-
Principii de bază ale optimizării
- Regula 80/20 (Pareto)
- Principele „Premature optimization is the root of all evil”
- Principele „Don’t optimize what you can’t measure”
-
Profilarea codului
- Introducere în profilare
- Profilarea timpului de execuție cu
timeit - Profilarea detaliată cu
cProfileșiprofile - Profilarea utilizării memoriei cu
memory_profiler
-
Tehnici de optimizare a codului
- Optimizarea algoritmilor și a complexității
- Utilizarea funcțiilor încorporate și a modulelor standard
- Evitarea utilizării globalelor și a atribuirilor neesențiale
- Folosirea list comprehensions și generator expressions
- Caching și memoization cu
functools.lru_cache
-
Optimizarea performanței în Python
- Optimizarea codului Python pur
- Utilizarea bibliotecilor externe de optimizare (NumPy, Cython, Numba)
- Optimizarea codului prin paralelism și concurență
-
Recapitulare și bune practici
- Rezumatul lecției și a tehnicilor prezentate
- Bune practici pentru optimizarea performanței și profilarea codului
Exemple și exerciții pentru fiecare subpunct:
Exemplu: Profilarea timpului de execuție cu timeit
import timeit
def suma1(n):
return sum(range(n))
def suma2(n):
return n * (n - 1) // 2
numar_repetari = 10000
n = 100
timp1 = timeit.timeit('suma1(n)', globals=globals(), number=numar_repetari)
timp2 = timeit.timeit('suma2(n)', globals=globals(), number=numar_repetari)
print(f"suma1: {timp1:.6f} secunde")
print(f"suma2: {timp2:.6f} secunde")
Exercițiu:
Profilati timpul de execuție al două funcții care calculează factorialul unui număr folosind o abordare iterativă și una recursivă.
Exemplu: Profilarea detaliată cu cProfile
import cProfile
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
def calculeaza_fibonacci(n):
for i in range(n):
fibonacci(i)
cProfile.run('calculeaza_fibonacci(20)')
Exercițiu:
Profilati detaliat o funcție care sortează o listă de numere folosind algoritmul Bubble Sort.
Exemplu: Caching și memoization cu functools.lru_cache
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci_cache(n):
if n <= 1:
return n
else:
return fibonacci_cache(n - 1) + fibonacci_cache(n - 2)
print(fibonacci_cache(100))
Exercițiu:
Optimizați o funcție recursivă care calculează al n-lea număr din șirul lui Padovan folosind memoization.
Rezumat:
În această lecție, am explorat conceptul de optimizare a performanței și am învățat cum să profilăm și să optimizăm codul Python. Am discutat despre principiile de bază ale optimizării și am introdus unelte precum timeit, cProfile și memory_profiler pentru a analiza performanța codului.
Am prezentat diverse tehnici de optimizare a codului, inclusiv optimizarea algoritmilor și acomplexității, utilizarea funcțiilor încorporate și a modulelor standard, evitarea utilizării globalelor și a atribuirilor neesențiale, folosirea list comprehensions și generator expressions, și caching și memoization cu functools.lru_cache.
De asemenea, am discutat despre optimizarea performanței în Python, prezentând biblioteci externe de optimizare, precum NumPy, Cython și Numba, și abordând optimizarea codului prin paralelism și concurență.
În final, am recapitulat lecția și am oferit bune practici pentru optimizarea performanței și profilarea codului. Aceste cunoștințe ne vor ajuta să scriem cod mai eficient și să identificăm și să remediem problemele de performanță în programele noastre.