Wednesday, January 2, 2013

Enhance Code Performance with Document.UserData

Kean Walmsley had a post quite a few years ago on the topic of Document.UserData, which is a HashTable type of object associated to the each document opened in AutoCAD. UserData can be used to store any type of data (type of object) identified by a unique key (type of string). To be aware, though, Document.UserData only available with opened document and is not persisted with the document. That is, it not part of drawing database, and only stays in memory with opened drawing document.

With the help of Document.UserData, it is possible to enhance our code performance in some cases. Here are a couple of scenarios.

1. Sometimes, we may need to search entire drawing fore some information before further process can continue. For example, I may want to get a some information of all entities that have Xdata embedded with certain application name. If the the drawing has tens of thousands of entities, the search could take some time.

After the search there could be different processes being performed based on the data obtained by the search. We certainly do not want to repeat the search each time a process based on the data obtained by the search, if possible. So, we could save the search result in Document.UserData when the search is complete. Then when following processes need the searched data, they can simply retrieve it from Document.UserData.

Well, in this case, it seems not much different from using class member variable when a command class is instantiated by a not-static command method. So, it is just another way to do things.

2. We can use Document.UserData to pass data between projects (DLLs). For example, I plan to do a set of tools that will run on a set of data, which could be based on a heavy drawing search or external database/service search. In this case, I can plan my development into multiple projects (agile development, delivering my workable tools one by one). So, I have one project doing the data gathering and store the obtained data in Document.UserData as in instance of a class (called Class1). In each individual tool project, it always go to Document.UserData to see if there is an object of Class1 stored or not. If it is, no data gathering is required and the tool's operation goes ahead.

Of course, if the data obtained in searching process could be changed, then some mechanism should be in place to refresh the data stored in Document.UserData. For example, if the data is related to per entity information, we may handle Database.ObjectModified event and determine if related information has been changed, hence the data in Document.UserData should be refreshed.