En aquesta secció, treballarem en diversos exercicis pràctics per aplicar les tècniques d'optimització d'algorismes que hem après fins ara. Aquests exercicis estan dissenyats per ajudar-te a identificar colls d'ampolla en el codi, millorar l'eficiència temporal i espacial, i aplicar tècniques de paral·lelització quan sigui possible.

Exercici 1: Optimització de Codi

Descripció

Tens un algorisme que calcula la suma de tots els nombres parells en una llista. Actualment, el codi és el següent:

def suma_parells(llista):
    suma = 0
    for i in range(len(llista)):
        if llista[i] % 2 == 0:
            suma += llista[i]
    return suma

Tasques

  1. Identifica les possibles millores en termes de claredat i eficiència.
  2. Reescriu el codi per fer-lo més eficient.

Solució

  1. Identificació de Millores:

    • Utilitzar un bucle for directe sobre els elements de la llista en lloc d'indexar amb range(len(llista)).
    • Utilitzar una comprensió de llistes per fer el codi més concís i possiblement més ràpid.
  2. Codi Optimitzat:

    def suma_parells(llista):
        return sum([x for x in llista if x % 2 == 0])
    

Explicació

  • La comprensió de llistes [x for x in llista if x % 2 == 0] crea una nova llista només amb els elements parells.
  • La funció sum() suma tots els elements de la llista resultant.

Exercici 2: Ús Eficient de Memòria

Descripció

Tens una funció que genera una llista de nombres quadrats fins a un nombre n. El codi actual és el següent:

def quadrats(n):
    result = []
    for i in range(n):
        result.append(i * i)
    return result

Tasques

  1. Identifica les possibles millores en termes d'ús de memòria.
  2. Reescriu el codi per fer-lo més eficient en termes de memòria.

Solució

  1. Identificació de Millores:

    • Utilitzar un generador en lloc d'una llista per reduir l'ús de memòria.
  2. Codi Optimitzat:

    def quadrats(n):
        return (i * i for i in range(n))
    

Explicació

  • Utilitzar un generador (i * i for i in range(n)) en lloc d'una llista permet generar els quadrats sobre la marxa, reduint l'ús de memòria.

Exercici 3: Paral·lelització d'Algorismes

Descripció

Tens una funció que calcula la suma de les potències de 2 fins a un nombre n. El codi actual és el següent:

def suma_potencies(n):
    suma = 0
    for i in range(n):
        suma += 2 ** i
    return suma

Tasques

  1. Identifica les possibles millores en termes de paral·lelització.
  2. Reescriu el codi per fer-lo més eficient utilitzant paral·lelització.

Solució

  1. Identificació de Millores:

    • Utilitzar la biblioteca multiprocessing per paral·lelitzar el càlcul de les potències.
  2. Codi Optimitzat:

    from multiprocessing import Pool
    
    def potencies(i):
        return 2 ** i
    
    def suma_potencies(n):
        with Pool() as pool:
            result = pool.map(potencies, range(n))
        return sum(result)
    

Explicació

  • La funció potencies(i) calcula la potència de 2 per a un valor i.
  • Utilitzem Pool de la biblioteca multiprocessing per paral·lelitzar el càlcul de les potències.
  • pool.map(potencies, range(n)) distribueix el càlcul de les potències entre múltiples processos.
  • Finalment, sumem els resultats amb sum(result).

Resum

En aquesta secció, hem treballat en diversos exercicis per optimitzar el codi en termes de claredat, eficiència temporal i espacial, i paral·lelització. Hem après a identificar colls d'ampolla i aplicar tècniques d'optimització per millorar el rendiment del nostre codi. Aquests exercicis són fonamentals per desenvolupar habilitats en l'anàlisi i disseny d'algorismes eficients.

© Copyright 2024. Tots els drets reservats