Optimización de software para niños
La optimización de software es el proceso de mejorar un software para que funcione de manera más eficiente o use menos recursos. Imagina que tienes un videojuego que a veces se traba o va lento; optimizarlo sería como hacer que funcione más rápido y sin problemas, o que ocupe menos espacio en la memoria de tu computadora.
Un programa puede ser optimizado para:
- Ejecutarse más rápidamente.
- Usar menos memoria o menos recursos.
- Consumir menos energía.
Contenido
¿Qué significa "optimizar"?
La palabra "optimización" viene de "óptimo", que significa lo mejor posible. Sin embargo, cuando hablamos de optimizar software, rara vez logramos que sea "perfecto" en todos los sentidos. Un programa optimizado suele ser el mejor para una tarea específica o para un tipo de usuario.
Por ejemplo, un programa podría hacerse más rápido, pero a cambio usar más memoria. Si la memoria es limitada, quizás sea mejor que el programa sea un poco más lento pero use menos memoria. Los ingenieros de software a menudo tienen que decidir qué es lo más importante a mejorar. Además, hacer que un software sea absolutamente perfecto puede llevar mucho tiempo y esfuerzo, más de lo que vale la pena. Por eso, la optimización se detiene cuando los beneficios son suficientes.
Equilibrar las mejoras
Optimizar un programa significa mejorar uno o dos aspectos de su rendimiento, como:
- El tiempo que tarda en funcionar.
- Cuánta memoria usa.
- Cuánto espacio ocupa en el disco.
- Cuánta energía consume.
Para mejorar un aspecto, a veces hay que sacrificar otro. Por ejemplo, si aumentas el tamaño de la memoria caché (un tipo de memoria rápida), el programa puede ir más rápido, pero también usará más memoria. Otras veces, mejorar el rendimiento puede hacer que el código del programa sea más difícil de entender.
A veces, un programador puede hacer que el software sea mejor para algunas cosas, pero menos eficiente para otras. Estos cambios se hacen para lograr un objetivo específico, como superar a un programa de la competencia.
¿Qué son los "cuellos de botella"?
Imagina que estás en una fila para entrar a un concierto y hay una puerta muy estrecha. Aunque haya muchas personas, solo pueden pasar unas pocas a la vez. Esa puerta estrecha es un "cuello de botella".
En el software, un cuello de botella es una parte del código que usa la mayor cantidad de recursos y hace que el programa se ralentice. Es como el punto más lento de todo el sistema.
La regla 80/20
En la informática, a menudo se aplica una regla llamada "principio de Pareto" o regla 80/20. Esto significa que, en promedio, el 80% de los recursos de un programa son usados por solo el 20% de sus operaciones. En el desarrollo de software, esto se traduce en que el 90% del tiempo que un programa está funcionando, lo pasa ejecutando solo el 10% de su código. Identificar y mejorar ese 10% es clave para la optimización.
A veces, añadir más memoria puede hacer que un programa funcione más rápido. Por ejemplo, un programa que filtra texto puede leer una línea, filtrarla y mostrarla. Esto usa poca memoria, pero puede ser lento. Si el programa lee todo el archivo primero, lo filtra y luego muestra los resultados, será más rápido, pero usará más memoria. Guardar resultados temporales en una memoria rápida (caché) también ayuda, pero requiere más memoria.
¿Cómo se optimiza el software?
La optimización puede hacerse en diferentes etapas del desarrollo de un programa:
Nivel de diseño
Desde el principio, al diseñar un programa, se pueden elegir algoritmos (pasos para resolver un problema) que sean muy eficientes. Una buena elección de algoritmo es una de las formas más importantes de mejorar el rendimiento.
Nivel de código fuente
Escribir un código claro y bien hecho desde el principio ayuda a evitar problemas de rendimiento. Después, se pueden hacer ajustes en el código para que sea más rápido, aunque a veces esto puede hacerlo un poco más difícil de entender.
Nivel de compilación
Cuando un programa se "compila" (se traduce de un lenguaje de programación a un lenguaje que la computadora entiende), se pueden usar herramientas especiales llamadas "compiladores optimizadores". Estos compiladores intentan que el programa final sea lo más eficiente posible.
Nivel de lenguaje ensamblador
En un nivel muy bajo, los programadores pueden escribir partes del código en "lenguaje ensamblador". Este lenguaje está muy cerca de cómo funciona el hardware de la computadora, y permite crear programas muy eficientes y pequeños, aprovechando al máximo las capacidades del procesador.
Optimización en tiempo de ejecución
Algunos programas pueden optimizarse mientras están funcionando. Esto lo hacen los "compiladores justo a tiempo" (JIT) o los programadores de ensamblador, que ajustan el programa según lo que esté haciendo en ese momento.
Optimización según la plataforma
La optimización puede depender o no de la plataforma (el tipo de computadora o sistema operativo).
- Las técnicas independientes de la plataforma funcionan bien en casi cualquier computadora. Por ejemplo, hacer que el programa use menos pasos o menos memoria en general.
- Las técnicas dependientes de la plataforma usan características específicas de un tipo de procesador o hardware. Esto significa que a veces hay que crear versiones diferentes del mismo código para distintas computadoras.
Diferentes formas de resolver un problema
Una misma tarea se puede resolver de varias maneras en programación, y cada una puede ser más o menos eficiente.
Por ejemplo, para sumar todos los números del 1 al N (donde N es cualquier número):
int i, sum = 0;
for (i = 1; i <= N; ++i) {
sum += i;
}
printf("sum: %d\n", sum);
Este código usa un bucle (un ciclo que se repite). Pero también se puede usar una fórmula matemática:
int sum = N * (1 + N) / 2;
printf("sum: %d\n", sum);
La segunda forma es mucho más rápida para números grandes, porque no necesita repetir el proceso muchas veces. La optimización a menudo consiste en elegir el método (algoritmo) más eficiente para una tarea, manteniendo el mismo resultado.
Optimización automática y manual
La optimización puede ser hecha automáticamente por los compiladores o manualmente por los programadores.
- Optimización automática: Los compiladores pueden hacer mejoras en partes pequeñas del código.
- Optimización manual: Los programadores optimizan el sistema completo, lo cual es más complejo. Ellos cambian el código para que el programa funcione mejor en general. Aunque es más costoso, puede lograr mejoras mayores.
Para saber dónde optimizar, los programadores usan herramientas llamadas "profilers". Estas herramientas les dicen qué partes del programa están usando más recursos (los cuellos de botella). A veces, los programadores creen saber dónde está el problema, pero el profiler puede mostrarles algo inesperado. Optimizar una parte del código que no es un cuello de botella no ayudará mucho al rendimiento general.
Una vez que se encuentra el cuello de botella, la optimización suele empezar por pensar si hay un algoritmo mejor. Por ejemplo, para ordenar una lista grande, se usa un algoritmo llamado "quicksort", que es muy eficiente. Pero si la lista ya tiene un cierto orden, se podría usar otro método aún mejor.
Después de elegir el mejor algoritmo, se puede empezar a optimizar el código. Esto puede incluir usar tipos de datos más pequeños o hacer cálculos con números enteros en lugar de números con decimales, que a veces son más rápidos.
Es importante saber que la optimización a veces hace que el código sea más difícil de leer. Por eso, las partes optimizadas deben estar bien explicadas con comentarios en el código, para que otros programadores puedan entenderlas y mantener el programa en el futuro.
¿Cuándo se debe optimizar?
Optimizar un programa puede hacer que el código sea más complejo y difícil de entender o de corregir. Por eso, la optimización se suele hacer al final del desarrollo del programa.
Un famoso informático, Donald Knuth, dijo una vez:
"Debemos olvidarnos de las pequeñas eficiencias, por ejemplo, el 97% del tiempo: la optimización prematura es la raíz de todos los males".
Esto significa que no hay que preocuparse por optimizar cada pequeña parte del código desde el principio. La "optimización prematura" ocurre cuando un programador se preocupa demasiado por el rendimiento al inicio del diseño de un programa. Esto puede llevar a un diseño complicado o incluso a errores, porque el código se vuelve difícil de manejar.
Es mejor diseñar el programa primero de forma sencilla y clara. Luego, una vez que el programa funciona, se puede usar un "profiler" para ver qué partes necesitan ser optimizadas. Un diseño simple y elegante es más fácil de optimizar en esta etapa.
En la práctica, los programadores suelen tener en cuenta el rendimiento desde el diseño, pero buscan un equilibrio entre un buen diseño y la optimización.
El tiempo que lleva optimizar
Optimizar un código ya existente no añade nuevas funciones y, a veces, puede introducir nuevos errores en un código que antes funcionaba bien. Como la optimización manual puede hacer el código menos claro, también puede afectar la compatibilidad. La optimización tiene un costo, y es importante asegurarse de que el tiempo y el esfuerzo invertidos valdrán la pena.
Un optimizador automático (como el de un compilador) también puede ser optimizado para que funcione más rápido o para que los programas que produce sean aún más eficientes. Compilar un programa con la optimización activada suele llevar más tiempo, pero esto solo es un problema en programas muy grandes.
Véase también
En inglés: Program optimization Facts for Kids