Big O explicado visualmente: qué escala, qué colapsa y cómo decidir

Entiende O(1), O(log n), O(n), O(n log n), O(n²) y O(2ⁿ) como patrones de crecimiento para tomar mejores decisiones de código.

9 min

Big O complexity curves / Curvas de complejidad Big O: O(1), O(log n), O(n), O(n log n), O(n²) y O(2ⁿ).

Big O sirve para responder una pregunta concreta: ¿cómo crece el trabajo cuando crece la entrada? No dice cuántos milisegundos tardará una función ni sustituye un benchmark. Describe la forma de la curva antes de que el volumen real convierta una decisión pequeña en un problema de producto.

Si una búsqueda tarda el doble cuando duplicas los datos, su comportamiento es distinto de otra cuyo costo apenas cambia. Esa diferencia importa más que una medición aislada en tu laptop.

Big O no mide velocidad. Mide cómo empeora el costo a medida que n crece.

01. Big O en 30 segundos

La letra n representa el tamaño de la entrada: usuarios, filas, nodos, caracteres, archivos, píxeles o eventos. La notación resume cuántas operaciones —o cuánta memoria— necesita una solución cuando n aumenta.

Seis patrones visuales de crecimiento Big OSeis patrones visuales de crecimiento Big O

ComplejidadImagen mentalEjemplo común
O(1)un salto directoleer por índice o clave
O(log n)descartar la mitadbúsqueda binaria
O(n)recorrer una vezbuscar en una lista
O(n log n)dividir y combinarordenamiento eficiente
O(n²)comparar paresloops anidados
O(2ⁿ)explorar combinacionesfuerza bruta combinatoria

Estas curvas no dicen si el código está bien o mal. Dicen qué tan sensible es al crecimiento. Para entradas pequeñas casi todas pueden parecer rápidas; la separación aparece cuando n deja de ser un dato de prueba y se convierte en tráfico, contenido o usuarios reales.

02. La escala cambia la decisión

Imagina, solo para comparar, que cada operación cuesta una unidad:

Complejidadn = 10n = 1.000n = 1.000.000
O(1)111
O(log n)41020
O(n)101.0001.000.000
O(n log n)4010.00020.000.000
O(n²)1001.000.0001.000.000.000.000

Comparación del crecimiento de operaciones para distintos tamaños de entradaComparación del crecimiento de operaciones para distintos tamaños de entrada

No es un benchmark exacto: ignora constantes, hardware y detalles de implementación. Es una lupa. Explica por qué dos soluciones indistinguibles con diez elementos pueden separarse brutalmente con un millón.

La regla práctica es simple: no optimices por intuición, pero tampoco ignores la forma de crecimiento. Primero identifica la curva; después mide la implementación real.

03. Tres decisiones que cambian la curva

Supón que necesitas responder muchas veces si existe un usuario. Recorrer el array es claro y cuesta O(n) por consulta. Construir un Set cuesta O(n) una vez, usa memoria adicional y permite consultas promedio O(1).

ts
function includesUser(users: { id: string }[], id: string) {
  return users.some((user) => user.id === id); // O(n)
}

const userIds = new Set(users.map((user) => user.id)); // O(n)
const exists = userIds.has(id); // O(1) promedio

No existe una opción universal. Para una sola consulta sobre diez elementos, el array probablemente sea mejor: menos código y ninguna estructura extra. Para miles de consultas sobre el mismo conjunto, pagar el índice una vez puede cambiar el costo total.

Si los datos ya están ordenados, la búsqueda binaria ofrece otro camino: cada paso elimina la mitad del espacio restante.

ts
function binarySearch(values: number[], target: number) {
  let low = 0;
  let high = values.length - 1;

  while (low <= high) {
    const mid = Math.floor((low + high) / 2);
    if (values[mid] === target) return mid;
    if (values[mid] < target) low = mid + 1;
    else high = mid - 1;
  }

  return -1;
}

Con un millón de elementos necesita alrededor de veinte divisiones, pero exige un invariante: la colección debe estar ordenada. La complejidad nunca aparece sola; viene acompañada de condiciones, memoria y costos de preparación.

Comparación visual entre recorrido lineal, búsqueda binaria y consulta con Map o SetComparación visual entre recorrido lineal, búsqueda binaria y consulta con Map o Set

04. Dónde empieza el peligro

O(n log n) es una frontera habitual para ordenar datos generales por comparación. Merge Sort divide y combina; Quick Sort particiona; Heap Sort usa una estructura de prioridad. La curva crece más que lineal, pero mucho menos que cuadrática.

El salto peligroso aparece cuando cada elemento vuelve a recorrer la colección. Un doble loop suele producir O(n²):

ts
function hasDuplicate(values: string[]) {
  for (let i = 0; i < values.length; i += 1) {
    for (let j = i + 1; j < values.length; j += 1) {
      if (values[i] === values[j]) return true;
    }
  }
  return false;
}

No todo loop anidado es automáticamente cuadrático: importa cuántas veces se ejecuta realmente cada nivel. Pero cuando ambos recorren n, duplicar la entrada puede cuadruplicar el trabajo. Un índice, hashing o una partición espacial puede cambiar la curva.

O(2ⁿ) es otra categoría. Aparece al explorar subconjuntos o decisiones binarias acumuladas. Con n = 50, probar todas las combinaciones deja de ser una optimización pendiente y se convierte en un problema imposible. Las herramientas habituales son memoización, poda, heurísticas y límites explícitos del producto.

Contraste entre comparación de pares O(n²) y explosión combinatoria O(2ⁿ)Contraste entre comparación de pares O(n²) y explosión combinatoria O(2ⁿ)

05. Lo que Big O no te cuenta

Big O elimina detalles para mostrar una tendencia. Esa simplificación es útil, pero tiene límites:

  • Constantes: una operación O(1) puede tener un costo fijo alto.
  • Caso promedio y peor caso: una tabla hash suele consultar en O(1) promedio, no como garantía absoluta.
  • Memoria: acelerar consultas con un Map o Set consume espacio adicional.
  • Distribución de datos: Quick Sort depende de sus particiones; un árbol depende de su balance.
  • Hardware y caché: dos soluciones con la misma complejidad pueden comportarse distinto en producción.

Por eso Big O y profiling no compiten. Big O te ayuda a detectar riesgos de escala antes de construir; un profiler te dice dónde se está gastando el tiempo real después de construir.

06. Checklist para decidir

Antes de cambiar una solución, responde:

  1. ¿Qué representa n y cuánto puede crecer?
  2. ¿La operación ocurre una vez o miles de veces?
  3. ¿Necesitas preparar u ordenar los datos antes de consultar?
  4. ¿Puedes intercambiar memoria por consultas más rápidas?
  5. ¿Importa el peor caso para UX, seguridad o infraestructura?
  6. ¿El problema aparece en mediciones reales o solo en teoría?

Prioriza claridad cuando los datos son pequeños y la ruta no es crítica. Cambia la estructura cuando la misma consulta se repite. Revisa loops anidados cuando n depende del usuario. Acota los problemas combinatorios antes de intentar microoptimizarlos.

Aprender Big O no consiste en memorizar fórmulas. Consiste en reconocer seis formas y hacer una pregunta antes de que el sistema crezca: ¿qué costo estoy comprando con esta decisión?


SESSION_ELAPSED00:00:00
LOCALE: ESENV: PROD