Rendimiento de las aplicaciones de IA
Índice
Introducción
Cuando vamos a desarrollar software es importante tener en cuenta la escalabilidad, complejidad y mantenibilidad. Es por lo que el análisis del rendimiento es un factor muy importante.
Los algoritmos es la parte pilar de nuestras aplicaciones y, por lo general, consumen muchos recursos del servidor. El rendimiento de nuestro algoritmo dependerá de la cantidad de información que le proporcionemos como entrada. A medida que ingresemos más datos, algunos algoritmos tendrán un rendimiento lineal, otros constantes, …
Es muy importante poder pronosticar el comportamiento, en tiempos de ejecución, de nuestros algoritmos utilizados en cualquier software de IA ya que un algoritmo mal optimizado puede hacer que nuestros costos de servidor sean más altos y estaríamos contratando servidores en vano. Además, una aplicación que sea lenta (ahora que estamos entrando al 5G) no es buena noticia.
No todos los algoritmos tienen el mismo rendimiento a medida que el volumen de datos que tiene que gestionar aumenta. Una de las técnicas para planificar el comportamiento de nuestros algoritmos es la notación Big O.
Notación Big O
Vamos a usar la siguiente definición:
En ciencias de la computación , la notación O grande se usa para clasificar algoritmos de acuerdo con cómo crecen sus requisitos de espacio o tiempo de ejecución a medida que aumenta el tamaño de entrada. Notación Big O
Es decir, la notación Big O es la representación relativa de la complejidad de un algoritmo. Veamos un ejemplo:
Ejemplo
A continuación vamos a desarrollar un ejemplo sencillo para comparar dos algoritmos usando la notación Big O. Con este ejemplo podemos ver la importancia de optimizar nuestros algoritmos lo máximo que podamos.
El problema a resolver es el siguiente:
Dado un entero “n“, calcular la suma de los “n” primeros números enteros.
Por ejemplo, si n es igual a 5, tenemos que sumar todos los números, desde 1 hasta 5, es decir, 1 + 2 + 3 + 4 + 5 = 15.
Usaremos dos algoritmos para resolver este problema. Veremos cuál de los dos algoritmos es más eficiente.
El primer enfoque, que llamaremos “Enfoque no óptimo“, consiste en sumar cada número, desde 1 hasta n. Este algoritmo tiene un rendimiento O(n). Por ejemplo, si “n” es igual a 5, tenemos que sumar desde 1 hasta 5, es decir, tenemos que realizar 5 operaciones para obtener el resultado. Si “n” es igual a 100, tenemos que sumar desde 1 hasta 100, de uno en uno, por lo que realizaríamos 100 operaciones para obtener el resultado.
El segundo enfoque, Enfoque Gauss, consiste en aplicar la siguiente formula:
Este algoritmo tiene un rendimiento O(1), es decir, el costo computacional es el mismo, independientemente de “n”. Por ejemplo, si n = 5, la suma es 5 * 6 / 2 = 15. Si n = 100, la suma es 100 * 101 / 2 = 5050. En ambos casos solo hemos realizado una operación.
Vamos a explicar ambos algoritmos usando el siguiente diagrama de flujo. Podemos ver que el enfoque Gauss tiene menos pasos (aunque no siempre será así) a diferencia del enfoque no óptimo.
Vamos a escribir los algoritmos en Python y R.
Python
Vamos a aplicar los dos algoritmos con el lenguaje de programación Python. En este código, hemos agregado time.sleep(1), esto detiene 1 segundo la ejecución. De esta manera podemos ver el rendimiento de cada enfoque.
R
El código en R lo pueden encontrar en el siguiente enlace.
Podemos ver que, a medida que aumenta “n”, el rendimiento del algoritmo Enfoque no óptimo empieza a aumentar linealmente, mientras el algoritmo Gauss se mantiene constante. Por lo que es muy importante dedicar recursos para poder optimizar nuestros algoritmos.
Tipos de Big – O
A continuación explicaremos los distintos tipos de Big O y un ejemplo, usando el código Python:
o(1): constante
La complejidad constante, nos dice que, independientemente del tamaño de los datos, el tiempo de ejecución y los recursos utilizados por nuestro algoritmo siempre será el mismo. Un ejemplo, es el algoritmo Gauss comentado anteriormente. Esto es lo ideal, pero es lo menos frecuente.
o(n): lineal
Un algoritmo es de complejidad lineal, cuando el tiempo de ejecución es proporcional al tamaño de nuestros datos. Un ejemplo, es el algoritmo Enfoque no óptimo.
o(log n): logarítmica
Un algoritmo es de complejidad logarítmica, cuando el tiempo de ejecución es proporcional al resultado logarítmico del tamaño de nuestros datos. Un buen ejemplo es la búsqueda binaria.
Python
A continuación veamos otros tipos con un ejemplo en Python:
o(nlog n):
Python
o(n2):
Python
o(2n): exponencial
Python
En la siguiente imagen (escrito en R, el código esta en el siguiente enlace), podemos ver el comportamiento de los distintas notaciones Big O:
En esta parte hemos aprendido la importancia de la notación Big – O y optimizar nuestros algoritmos.
Cualquier duda, opinión, comentario, etc, pueden ponerlo en los comentarios.
Una respuesta a «Rendimiento de las aplicaciones de IA»