La notación O grande es la manera en que la informática describe cuánto crece el coste de un algoritmo cuando crece el tamaño de su entrada, ignorando todo lo demás. Decir que la búsqueda binaria es O(log n) y la búsqueda lineal es O(n) no dice cuánto tarda ninguna de las dos en ningún ordenador; dice que si la lista se hace mil veces más larga, la primera necesitará unos diez pasos más y la segunda mil veces más pasos. Es una notación de crecimiento, no de velocidad, y su utilidad viene de que el crecimiento es lo único que importa cuando n es grande: una constante, por fea que sea, la puede compensar una máquina mejor, y un exponente no lo compensa nada.
La figura de esta página no dibuja fórmulas sino recuentos. Para cada tamaño de entrada entre unas decenas y varios miles, ejecuta de verdad, en el navegador del lector, cinco algoritmos sobre datos aleatorios y cuenta cuántas comparaciones hacen: buscar un elemento que no está en una lista, con búsqueda lineal y con búsqueda binaria; ordenar la lista, con el método de la burbuja y con el de mezcla; y enumerar todos los subconjuntos de un conjunto, que es lo que hay que hacer cuando no se conoce nada mejor. Los puntos son las medidas; las líneas de trazos, la curva teórica de cada orden, ajustada a las medidas por un solo factor. Que los puntos caigan sobre las líneas es la comprobación de que la notación describe algo real.
Lo primero que se ve es la distancia entre órdenes. Para una lista de mil elementos, la búsqueda binaria hace unas diez comparaciones y la lineal mil; ordenar por mezcla cuesta unas diez mil y ordenar por burbuja, medio millón. Con dos mil elementos, la binaria hace una comparación más, la lineal el doble, la mezcla algo más del doble y la burbuja cuatro veces más. Esa es la definición en acción: el orden de un algoritmo dice cómo escala su coste al multiplicar n. Un algoritmo O(n²) multiplica su coste por cuatro cada vez que la entrada se dobla; uno O(n log n) por poco más de dos; uno O(log n) apenas lo mueve. Y la curva de 2ⁿ, la de los subconjuntos, solo llega en la figura hasta n = 22, porque para n = 40 harían falta un billón de pasos y para n = 100 no bastaría la edad del universo. Los problemas cuyo mejor algoritmo conocido es de ese tipo se llaman intratables, y buena parte de la informática teórica consiste en averiguar cuáles lo son.
Lo segundo es por qué el eje vertical está en escala logarítmica. Al pulsar el botón que la quita, la burbuja se convierte en una pared y las otras cuatro curvas se aplastan contra el eje, indistinguibles. Los órdenes de crecimiento se diferencian por factores multiplicativos, no aditivos, y solo una escala que convierta multiplicar en sumar los muestra a la vez. Esa misma razón explica por qué la notación ignora las constantes: en la escala que importa, un factor constante es un desplazamiento vertical, y las curvas de órdenes distintos acaban cruzándose, pase lo que pase con las constantes, en algún n suficientemente grande.
La definición formal es más modesta de lo que su uso sugiere. Decir que una función f(n) es O(g(n)) significa que existe una constante c tal que, a partir de cierto n, f(n) ≤ c·g(n): g es una cota superior del crecimiento de f, salvo constante y salvo los primeros valores. La notación la introdujo Paul Bachmann en 1894 en un tratado de teoría de números, la popularizó Edmund Landau en 1909, y la informática la adoptó cuando Juris Hartmanis y Richard Stearns fundaron la teoría de la complejidad computacional en 1965 midiendo el coste de los algoritmos como función del tamaño de la entrada. Donald Knuth, en una nota de 1976 que sigue siendo la referencia, señaló que la mayoría de los informáticos usan la O grande para decir «crece exactamente como», que es lo que significa la notación Θ (theta), y que lo hacen porque casi siempre la cota superior que se conoce es también la real. Cuando se dice que la ordenación por mezcla «es n log n», se está diciendo Θ, aunque se escriba O.
Hay tres cosas que la notación no dice y que conviene recordar al leerla. No dice nada del caso concreto: la búsqueda lineal de la figura busca un elemento que no está, su peor caso, y si el elemento estuviera al principio terminaría en un paso. No dice nada de n pequeño: para listas de diez elementos, un algoritmo cuadrático sencillo suele ganar a uno n log n complicado, y las bibliotecas de ordenación reales cambian de algoritmo por debajo de cierto tamaño. Y no dice nada de la memoria, ni de la caché, ni del paralelismo, que en una máquina real pueden pesar más que el número de comparaciones. Lo que sí dice es lo que los puntos de la figura muestran al subir el deslizador: hacia dónde va cada curva, y por tanto qué algoritmo dejará de funcionar primero cuando los datos crezcan. Es una notación para prever el futuro de un programa, y para eso sirve mejor que cualquier cronómetro.


