Quinto y último post de nuestra serie dedicada al Green Software, en este caso orientado a cómo generar un código más eficiente.
Aprenda a optimizar y desconfíe de los robots
Como decíamos, cuanta menos memoria asigne nuestra aplicación y menos ciclos de computación conlleve la ejecución de nuestro código, menores emisiones de gases de efecto invernadero provocará nuestro software. Con esto en mente, decidimos idear una estrategia de optimización para uno de nuestros proyectos existentes.
La primera preguntar era obvia: ¿debíamos optimizar toda la aplicación? La respuesta es no. Cuando una aplicación lleva viva cierto tiempo, la cantidad de código que la compone puede ser considerable. Por eso, lo mejor es centrarse en los llamados hot spots: a menudo un conjunto muy pequeño de métodos son los que procesan la gran mayoría de las peticiones, y es en ellos donde deberíamos centrar nuestros esfuerzos.
La segunda pregunta era incómoda: ¿estás acostumbrado a optimizar código? Y la respuesta, en el caso de muchos programadores, también es no. Porque, no nos engañemos: hoy en día, la mayor parte de programadores somos en realidad consumidores de APIs, librerías y frameworks. Las estructuras de datos y los algoritmos no forman parte del día a día del programador medio, y hacer un código optimizado no es su prioridad: lo que debe hacer es sacar adelante historias de usuario utilizando el framework de moda.
Por tanto, si no estás acostumbrado a optimizar código, puedes empezar por echar un vistazo a recopilaciones de consejos de optimización como este, o puedes preguntar a ChatGPT. Sin embargo, ninguna de estas dos estrategias es infalible, por lo que, hagas lo que hagas, asegúrate de que de verdad estás mejorando el código haciendo mediciones con alguna herramienta de benchmarking.
En nuestras pruebas, usamos BenchmarkDotNet, una librería de código abierto para .NET que se encarga de todo el proceso de ejecución del benchmark, desde la ejecución del código hasta la presentación de los resultados, y proporciona diagnósticos detallados, como el tiempo de ejecución, el uso de memoria, las veces que se invoca el recolector de basura (GC), etc. Y no es un proyecto marginal: lo usa la propia Microsoft en sus desarrollos, .NET incluido.
Una de nuestras pruebas consistió en tomar código de una de nuestras aplicaciones, pedir a ChatGPT que nos ayudara a optimizarlo, y ejecutar la herramienta de benchmarking para comprobar si, efectivamente, la optimización era cierta. Sin entrar en detalles, estos fueron los primeros resultados:
Es decir, el método optimizado por ChatGPT era 6 veces más lento que el original, asignaba 464 B que no asignaba el original y, además, hacía una llamada al recolector de basura que no hacía el original.
Empleada de Ilitia al descubrir que ChatGPT también se equivoca
Aunque, tras varios prompts adicionales, conseguimos llegar a un método más optimizado, el fiasco anterior nos hizo más sabios, pues aprendimos que:
- ChatGPT puede ayudarnos a optimizar código, pero…
- ChatGPT no es la Panacea. A veces se equivoca, o no entiende el prompt que le hemos dado, y es necesario afinarlo.
- No podemos confiar a pies juntillas en sugerencias de ChatGPT ni en recopilaciones hechas por «expertos». Lo mejor es hacer pruebas con una herramienta de benchmarking como BenchmarkDotNet. Una prueba vale más que mil suposiciones.
Aplicaciones web y viejas-nuevas buenas prácticas
Si te dedicas al desarrollo web y, como yo, recuerdas el ruido que hacía un módem de 56k al conectarse a internet, se pueden asumir dos cosas sobre ti: deberías tomar yogures de los que bajan el colesterol y sabes lo que es optimizar una página web para que cargue rápido. Y, pese a la llegada de las conexiones rápidas y los anchos de banda de hoy en día, es algo que no hemos dejado de lado del todo: con la irrupción de los dispositivos móviles y sus limitadas conexiones de datos tuvimos que desempolvar aquellos conocimientos y adaptarlos al nuevo entorno tecnológico.
Ilitio viejoven tomando fresas voladoras mientras optimiza una web escrita en Klingon
El caso es que, si bien en la actualidad las conexiones rápidas abundan, no debemos dejar de lado la optimización, pues, cuanto más pesa una web, más consumo eléctrico requiere transmitirla desde el servidor hasta nuestros dispositivos (con las consiguientes emisiones de gases de efecto invernadero).
Por eso, y con el fin de reducir nuestras emisiones el máximo posible, en Ilitia nos hemos propuesto recuperar aquellas buenas prácticas (¿recuperar? nunca las perdimos, ejem) para que en nuestros desarrollos sólo viajen los datos estrictamente necesarios entre clientes y servidores. Así, siguiendo las recomendaciones de la Green Software Foundation más nuestra propia experiencia, estamos repasando nuestras aplicaciones para asegurarnos, entre otras cosas, de:
Usar versiones recientes de software y librerías. Los desarrolladores de frameworks y librerías front-end importantes como Angular o Vue.js trabajan constantemente en la optimización de sus productos. Con cada nueva versión, se implementan mejoras no solo en el rendimiento, la velocidad y la eficiencia del código, sino también en la reducción, en la medida de lo posible, del tamaño de dichos frameworks y librerías.
Utilizar imágenes del tamaño adecuado. A menudo se usan imágenes más grandes (en píxeles) de lo que después se muestra en pantalla. Por norma, una imagen mayor en píxeles tendrá mayor peso en bytes, por lo que se recomienda que las imágenes no excedan por mucho el tamaño (en píxeles) que se vaya a mostrar en la pantalla. Cuanto menor sea el tamaño de la información transmitida por la red, menos energía será necesaria para transmitirla (y, por tanto, menos emisiones se producirán). Sirva como ejemplo la mejora que obtuvimos al reducir el tamaño del logo de una de nuestras aplicaciones:
Usar formatos de imágenes modernos y algoritmos de compresión de imágenes eficientes. Si bien, en general se recomienda utilizar formatos modernos, como WebP y AVIF, que permiten mayor compresión sin pérdida de calidad, nosotros hemos obtenido resultados muy notorios sometiendo las imágenes a algoritmos de compresión más eficientes, pero sin cambiar el formato. Existen numerosos servicios gratuitos que ofrecen compresión de imágenes. En nuestras pruebas hemos utilizado TinyPNG, que es un proyecto consolidado y respaldado por importantes compañías del sector:
https://tinypng.com/
Los resultados (muy significativos) de la compresión de las imágenes de uno de nuestros proyectos son los que siguen:
Activar la compresión GZip en nuestros servidores web, ya sean clásicos (IIS on premise) o modernos (nginx sobre Kubernetes).
Cachear tanto contenido como sea posible, ya sea información que viaje entre el servidor y los dispositivos en que se consumen nuestras aplicaciones, o entre el servidor y sus fuentes de datos.
De este modo, lo que antes se hacía meramente para mejorar la experiencia del usuario (evitando que la carga de una página conllevara prolongados tiempos de espera) ahora lo hacemos para evitar emisiones de gases de efecto invernadero.
José Ángel Fernández
Full-Stack Senior Software Engineer at ilitia Technologies
Edición: Jon Burguera