Conținut curs
Python Avansat
Despre lecție
  1. Introducere în optimizarea performanței

    • Importanța optimizării performanței în dezvoltarea software
    • Identificarea bottleneck-urilor și alocarea resurselor
  2. 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”
  3. Profilarea codului

    • Introducere în profilare
    • Profilarea timpului de execuție cu timeit
    • Profilarea detaliată cu cProfile și profile
    • Profilarea utilizării memoriei cu memory_profiler
  4. 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
  5. Optimizarea performanței în Python

    • Optimizarea codului Python pur
    • Utilizarea bibliotecilor externe de optimizare (NumPy, Cython, Numba)
    • Optimizarea codului prin paralelism și concurență
  6. 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

python
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

python
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

python
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.