En estos días hemos estado poniéndole carga a MonoUML, gracias a una aplicación de ingeniería inversa que está haciendo Mario.
El programa genera un modelo UML a partir de un ensamblado, metiéndose bastante en detalle en todos los elementos afectados, tanto propios del ensamblado como referenciados directa o indirectamente. Esto hace que se obtenga información minuciosa de, por ejemplo, toda la mscorlib.dll.
Esto permitió detectar varios problemas:
- Alto consumo de memoria: aproximadamente 3,5 KB de RAM por cada clase vacía (!!!).
- Demoras para deserializar modelos grandes.
- Demoras tremendas para eliminar, por ejemplo, un paquete completo con todas las referencias a este y a sus los elementos contenidos.
Estos problemas surgen como resultado de la implementación actual de la librería para UML 2 de ExpertCoder (EC), que evidentemente necesita una revisión.
Yo creo que el quid de la cuestión está relacionado a la infraestructura para mantener los esquemas de propiedades de UML que se monta cada vez que se crea un objeto. Esta infraestructura permite que el valor de una propiedad pueda ser un subconjunto del valor de otra (ejemplo: todo Element tiene un conjunto de comentarios llamado ownedComment, que es un subconjunto de otro atributo llamado ownedElement; la idea es que todo elemento de ownedComment pertenece también a ownedElement).
Considero que, para solucionar este problema, debe implementarse un esquema perezoso de instanciación de esta infraestructura, de manera tal que se genere en tiempo de ejecución sólo para las propiedades que son realmente utilizadas.
Este fin de semana haré unas pruebas preliminares, tratando de optimizar Package, Class, DataType, Property y Operation, ya que son los elementos de modelo más utilizados en los ejemplos que tengo a mano, y si puedo bajar considerablemente el consumo de memoria y los tiempos de deserialización, aplicaré los cambios al resto de las clases.
Será un trabajo pesado y doloroso, pero es necesario hacerlo.