2.3 Técnicas de Optimización en Algoritmos#

Una vez que un algoritmo funciona correctamente y comprendemos su complejidad computacional, el siguiente paso lógico es la optimización. Optimizar significa refactorizar el código para que consuma menos recursos (tiempo de procesamiento y memoria RAM) y sea más fácil de leer y mantener, sin alterar su resultado final.

A continuación, exploramos las técnicas fundamentales para lograr algoritmos más eficientes.


A. Principio DRY (Don’t Repeat Yourself)#

El principio «No te repitas» establece que ninguna pieza de lógica debería aparecer duplicada en el código. Si te encuentras copiando y pegando el mismo bloque de instrucciones múltiples veces, es momento de optimizar.

  • Solución: Agrupar la lógica repetitiva dentro de Ciclos o Funciones.

  • Beneficio: Si la regla de negocio cambia (por ejemplo, el impuesto pasa del 19% al 15%), solo debes modificar el código en un solo lugar, reduciendo drásticamente los errores de mantenimiento.


B. Salidas Tempranas (Early Exit / Break)#

Cuando realizamos búsquedas o validaciones dentro de un ciclo, no siempre es necesario recorrer todos los datos. Si ya encontramos la respuesta que buscábamos o detectamos un error que invalida el proceso, debemos detener la ejecución inmediatamente.

  • Uso del comando break: Interrumpe un ciclo completo.

  • Uso del comando return (en funciones): Devuelve el resultado y sale del subprograma.

Ejemplo ineficiente: Un ciclo que revisa 10,000 facturas para ver si existe la factura #5. Si la encuentra en la posición 2, igual revisa las 9,998 restantes.

Ejemplo optimizado:

factura_buscada = 5
for factura in lista_facturas:
    if factura['id'] == factura_buscada:
        print("Factura encontrada")
        break  # Detiene el ciclo inmediatamente

C. Uso de Estructuras de Datos Eficientes (Sets)#

En la sección anterior vimos la superioridad de los diccionarios sobre las listas para búsquedas por clave. Otra estructura vital para la optimización en Python son los Conjuntos (Sets).

  • Características: Son colecciones desordenadas de elementos únicos. No permiten duplicados.

  • Ventaja Computacional: Al igual que los diccionarios, los conjuntos tienen una complejidad de tiempo \(O(1)\) para verificar si un elemento existe (membresía).

  • Aplicación: Si necesitas cruzar dos bases de datos enormes para ver qué clientes de la lista A también están en la lista B, convertir las listas a Sets hará que el proceso pase de tardar minutos a milisegundos.

# Búsqueda extremadamente rápida usando Sets
clientes_vip = {"Juan", "Ana", "Carlos"}

if "Ana" in clientes_vip:  # Esta operación toma tiempo O(1)
    print("Aplicar trato preferencial")

D. Comprensión de Listas (List Comprehensions)#

Esta es una técnica específica de Python que permite crear listas nuevas a partir de listas existentes de una manera mucho más concisa y rápida que usando un ciclo for tradicional. Python optimiza estas expresiones a nivel interno (en el lenguaje C subyacente), ejecutándolas a mayor velocidad.

Código Tradicional (Toma 3 líneas):

precios_con_iva = []
for precio in lista_precios:
    precios_con_iva.append(precio * 1.19)

Código Optimizado (Toma 1 línea):

precios_con_iva = [precio * 1.19 for precio in lista_precios]