jump to navigation

Optimizando aplicaciones Diciembre 24, 2006

Posted by eugenioserrano in General.
add a comment

Aprovechando para pulir los últimos de detalles antes de liberar la versión final de Cooperator Framework, estuve estos días optimizando un proceso que ya tenemos en producción desarrollado sobre nuestro Cooperator y que lee y escribe intensivamente en la base de datos.

Para la optimización use estas 3 herramientas.

1) SQL Profiler: Con el pude ver las conexiones abiertas por la aplicación, a que Stored Procedures estaba llamando en cada caso, cuantas lecturas/escrituras se hacian en cada operación, etc.… Ver más.

2) CLR Profiler: Es una herramienta que básicamente chequea como  actua el Garbage Collector y como es el ciclo de vida de los objetos dentro de nuestra aplicación. Muy buena, también me permitió ver que objetos tenía mas cargados, que tipos eran más usados, etc.. Ver más.

3) Enterprise Performance Tool: Aunque no funciona del todo bien en Windows Vista, la utilicé para “medir”, cuales son los métodos que más tardan en ejecutarse, cuales son los métodos más llamados, etc.. Ver más.

Recomiendo revisar los procesos con esas 3 herramientas ya que se puede ajustar muchísimas cosas que de otra forma no se pueden ver. Yo en mi caso, ajustando tanto las librerías de clases base de Cooperator, como el código de mi aplicación logre bajar a más de la mitad el tiempo en que  se ejecutaba el proceso y a la vez consumir menos recursos.
Por ejemplo con la herramienta de rendimiento de Visual Studio 2005, me di cuenta que estaba llamando más de 1.000.000 de veces a un determinado método. Bueno después de cambiar algunas cosas logre reducir notablemente ese caso particular poniendo una colección en un diccionario de generics y preguntando si tal objeto estaba en el diccionario… Es impresionante como caminan los diccionarios en .Net 2,0 ! 

Saludos,
Eugenio

Cuando Debug no es igual a Release Diciembre 24, 2006

Posted by eugenioserrano in General.
1 comment so far

¿ Usted cree en las brujas ? Hay algunos dias que me hago esa pregunta … :)

Les cuento de un error de por más interesante que me estaba dando una aplicación que lee y escribe datos intensivamente sobre una base de datos SQL Server y que me motivó a escribir esta entrada en mi blog.

Es un error súper extraño y gracioso a la vez. Antes que nada, mostremos el stack del error:

Stack Trace
   at System.Data.SqlClient.SqlTransaction.Zombie()
   at System.Data.SqlClient.SqlInternalTransaction.ZombieParent()
   at System.Data.SqlClient.SqlInternalTransaction.CloseFromConnection()
   at System.Data.SqlClient.TdsParser.Deactivate(Boolean connectionIsDoomed)
   at System.Data.SqlClient.SqlInternalConnectionTds.InternalDeactivate()
   at System.Data.SqlClient.SqlInternalConnection.Deactivate()

¿¿¿¿ System.Data.SqlClient.SqlTransaction.Zombie() ????
Pues sí, y sinceramente jamas habia visto este error ni nada parecido !!

Está bien que era sábado cerca de las 12 de la noche, pero el Zombie en ese caso debería ser yo y no tenía porque serlo ADO.Net, a no ser que las brujas existan…  :-)

Lo peor de todo esto es que este error sucedía solamente cuando compilaba mi aplicación en Release y no en Debug !
Con Debug funcionaba todo perfectamente tal cual estaba programado. :(

En otro caso, aleatoriamente me daba: referencia no establecida a instancia de objeto.  Empecé entonces a revisar todo el proceso paso a paso para ver si mis objetos eran Thread Safe, si mis colecciones están trabajando correctamente, etc.. Pero como en Debug la aplicacion funcionaba correctamente era evidente que por mas que me pase horas y horas recorriendo paso a paso mi aplicacion no iba llegar al problema.
Busqué el error del “Zombie” en internet y prácticamente no encontré ninguna información acerca del mismo, y en la ayuda nada de nada…
Termine apagando mi equipo y me fui a hacer un poco de vida familiar antes de irme a dormir.

Hoy domingo mi pequeña hija me despertó tempranito y aproveche para ponerme a estudiar el misterioso caso del Zombie que tenía en mi Pc. :P

Después de un par de horas de revisar mi código buscando sin éxito algún problema me puse a revisar las opciones de compilación de cada proyecto ya que era muy extraño que en Debug funcionara y en Release no.
Al fin encontré como solucionar el problema, y era que en Release, uno de mis ensambles tenía en la opción Generar Información de Depuración = None, mientras que otros tenían pdb-only.  En Debug esto es por defecto Full.

¿ Conclusión que saco ?

Hay que usar para todos los proyectos que forman parte una aplicación la misma configuración avanzada de compilación. Esto es: None para todos, ó pdb-only para todos, ó Full (Debug) para todos, ya que de lo contrario obtendremos resultados inesperados.

Bueno, con eso mi aplicación quedó andando (y muy rápido), pero si alguien me puede explicar este extraño comportamiento se lo agradeceré….

Aquí paso las ventanas tanto en Visual Basic como en C# de cómo cambiar esta configuración.

compilacion1.jpg

compilacion2.jpg