¿Cuál es la necesidad de determinar la complejidad temporal de un algoritmo o código?

En la era de la nube, ahora más que nunca, necesitamos comprender el impacto del código sh * t en el funcionamiento de los sistemas y plataformas, ¡porque los costos informáticos son una preocupación arquitectónica!

Cuando decimos:

[matemáticas] O (n ^ 2) [/ matemáticas]

Sabemos que a medida que aumenta el número de elementos, este algoritmo comenzará a tomar n veces más operaciones que hacerlo en tiempo lineal (O (n)). Eso significa que si se le cobra por cómputo, algo que toma 100 milisegundos, realmente se puede hacer en 10 ms y con la multitarea, esto significa que puede obtener aproximadamente 9 o 10 veces más procesamiento por dólar de gasto.

A veces ves gente que dice “Sí, ¡pero puedo poner índices en mi base de datos!”

Y yo soy como …

Debido a que los índices funcionan mejor al unir y evitar escaneos de tabla, pero el efecto de cada índice es naturalmente lineal. Déjame darte otro ejemplo:

La base de datos tiene 3 tablas y desea unirlas todas. la mesa del medio es una de muchos a muchos. Un clutz escribirá algo como esto:

seleccione my_life.dear_gawd_why, is_a.person_asking_this_question
from (unión interna my_life is_a en my_life.id = is_a.mylife_id)
desperdicio de unión interna en waste.id = is_a.waste_id
donde waste.id = @someshit

Y decir

“Sí, ¡optimizaré mis índices! Soy el rey del mundo!

Luego les daré una bofetada y reescribiré esto como:

seleccione my_life.dear_gawd_why, is_a.person_asking_this_question
from (seleccione * from is_a donde is_a.waste_id = @someshit) shorty inner únete a my_life en my_life.id = shorty.mylife_id)

Entonces, ¿por qué reescribí eso así?

Combinatoriamente, la primera opción da como resultado que todos los índices se unan tanto en la primera como en la segunda tabla, y el resultado de eso, se una en la tercera tabla. Si imaginas los números como

  • my_life = 10,000 registros
  • is_a = 17,000 registros
  • desperdicio = 1,000

Y waste.id id de coincidencia = @someshit es decir, 100.

Esto da como resultado un índice almacenado en la memoria del producto cartesiano de 170,000,000,000 de registros (que tiene sus propios problemas de complejidad de espacio: ¿tiene 170GB + en su máquina? Está fuera de la memoria virtual) que luego debe rastrear debajo del capó para llegar al máximo 1 x 100 x 10,000 = 1,000,000 de registros coincidentes.

Por el contrario, mi camino te da el prefiltro de 100 registros para unirte. Lo que significa que el máximo que podría tener que rastrear es 10,000 x 100 x 1,000 = 1,000,000,000 para luego encontrar el máximo de 1,000,000 de registros coincidentes. 170 veces más rápido, incluso con índices.

Es este tipo de combinatoria lo que diferencia a los ingenieros de software reales de los “programadores”, no es que quiera perjudicar a los programadores.

Si desea otro consejo, hice uno hace mucho tiempo para mostrar la diferencia, incluso contra la vainilla, de las bibliotecas de objetos de lenguaje fuera de la caja.

Optima local codiciosa, no una marca mundial óptima Codementor

Supongamos que le hago la siguiente pregunta: ¿ qué algoritmo debo usar para resolver este problema?

Normalmente, el objetivo es encontrar el algoritmo más eficiente para resolver un problema. Me gustaría darle una razón matemática de por qué debería elegir un algoritmo sobre otro. Suponiendo que use suposiciones razonables, es una forma bastante confiable de determinar la eficiencia de un algoritmo que es independiente de la máquina . Además, los problemas tienen normalmente un número infinito de instancias, por lo que desea una forma de capturar la eficiencia de todas las instancias de un problema. Es algo que utilizamos para analizar el tiempo de ejecución de los algoritmos, que no es necesario implementar. No es necesario implementar los algoritmos para realizar esta actividad.

También hay razones prácticas para considerar, como algunos dicen, el comportamiento asintótico también puede interpretarse como qué tan bien se escala el algoritmo con respecto al tamaño de entrada . A medida que las personas usan instancias más grandes, la eficiencia de una implementación de un algoritmo puede hacer o deshacer el rendimiento de un sistema.

No hay “necesidad”, pero a menos que esté escribiendo una aplicación trivial, debe tener al menos una idea del rendimiento general de los algoritmos que utiliza. Elegir los algoritmos correctos puede ser muy útil para no necesitar optimizar el rendimiento más adelante. Como eso se hace en tiempo de diseño, no cuesta nada elegir un algoritmo O (N) u O (N lg (N)) sobre un algoritmo O (N ^ 3). Pero, si sabe que N no es mayor que, digamos 10, no hay razón para escribir una clasificación compleja y altamente eficiente cuando una clasificación de burbuja simple servirá. O bien, un analizador de descenso recursivo escrito a mano y de fácil mantenimiento puede ser mejor que un analizador eficiente, no mantenible y generado. Por dos razones, primero la sobrecarga en el algoritmo “eficiente” puede ser más alta que el costo de ejecución del tipo menos eficiente para N pequeño, y en segundo lugar, es poco probable que la diferencia de rendimiento (si la hubiera) sea notada.
Por lo tanto, no necesita hacer un análisis algorítmico para determinar el complejo exacto, pero al menos debe tener una idea de lo que está haciendo.

Suponga que desea un algoritmo que funcione con n = 100,000 elementos de datos. ¿Cuál debería usar, un algoritmo O (n) oy O (n ^ 2)? En este caso, n ^ 2 es 100,000 veces más grande que ny la diferencia de 100,000 generalmente abrumará las constantes ocultas en la notación big-O. Suponga que el algoritmo O (n) se ejecuta exactamente 100,000 veces más rápido que el algoritmo O (n ^ 2). Entonces, si el algoritmo O (n) se ejecuta en 5 minutos, el algoritmo O (n ^ 2) tomará aproximadamente 3.5 días.

La ‘necesidad’ es para fines de ampliación

Lo mismo con la complejidad del espacio.

Nota: la notación grande ‘O’ oculta constantes, razón por la cual la mayoría de las rutinas de la biblioteca usan la ordenación rápida en lugar de la ordenada, lo que garantiza O (n log n)