Optimización: buenas prácticas

La optimización es un tema muy importante en un proyecto. En
algunos más que en otros dada su propia idiosincrasia y el escenario de
producción en el que se van a desenvolver, ya que no es interesante invertir
esfuerzo en optimizar algo que ya funciona bien, no hay que llevar al extremo
el hecho de que todo se puede optimizar, pero obviamente siempre es un tema importante. 

Se puede (y se debe) tener la optimización en mente desde
las fases más tempranas, sobre todo si está claro que el proyecto va a requerir
estar bien afinado para dar los resultados esperados.  

Sin embargo, es interesante recordar que lo importante es que
los equipos de desarrollo pongan el esfuerzo en el lugar adecuado en el momento
adecuado. No es eficiente pretender mejorar cada bucle del código para arañar
unos milisegundos, cuando por otro lado pueden estar ejecutándose 20
procedimientos almacenados para recuperar datos, siendo la mayoría innecesarios
en ese momento.

En paralelismo de computadoras es conocida la Ley de Amdahl,
que como dice Wikipedia:

“…se usa para averiguar la mejora máxima de un sistema
cuando solo una parte de éste es mejorado.”

Esta ley es igual de útil en paralelismo que para la
optimización de aplicaciones en general, ya que prácticamente siempre hay un único
agujero negro de rendimiento que, una vez optimizado, mejora el resultado final
dramáticamente y hace desaparecer el problema que existía.

Teniendo esto en cuenta, lo importante a la hora de afrontar
la optimización de una aplicación, subsistema, caso de uso, pantalla,
funcionalidad, etc. es descubrir cuál es ese agujero negro responsable
principal de la caída del rendimiento y optimizarlo. No intentar optimizar a
ciegas. Para esto podemos ayudarnos de herramientas útiles como profilers, si
las trazas y pruebas sobre el código no son suficientes para revelar dónde se
encuentra el problema principal.

Para ilustrar lo anterior con un ejemplo clásico: imaginemos
un caso de uso en el que el tiempo de ejecución dedicado a la lógica de negocio
consume un 15% del total, el 10% se dedica a carga de controles e interfaz
gráfica y el 75% restante nos encontramos esperando por la carga de datos desde
la base de datos.

En este escenario resulta fácil ver como no es eficiente
intentar optimizar la lógica de negocio, ni la interfaz de usuario, sino
averiguar qué falla en la recuperación de datos: ¿puede ser código ADO.NET muy
ineficiente? ¿Puede ser que estemos recuperando datos que no se necesitan en su
totalidad en este caso de uso? ¿Puede ser que inspeccionando el plan de
ejecución del procedimiento almacenado que se invoca veamos que hace cosas innecesarias
o que podrían mejorarse bastante mediante mejor código T-SQL?

La buena práctica para plantear la optimización, por tanto, consiste
en averiguar dónde está el performance penalty y optimizarlo,  no en dedicar esfuerzos a otras partes cuyo
impacto en el cómputo total es sólo el 10% ó 15%, porque optimizando esto la
mejora será casi imperceptible, el problema está en el 75%.