Design considerations

When you design the types of attributes you are going to use, you need to consider the following factors: storage sizes, global declarations, and multithreading issues.

Do not use internal attributes if storage size is small

In deciding whether to use a surrogate to point to an internal shared attribute or to simply use the attribute directly, consider the size implications of a TAttribute versus a TSharedAttribute and a TInternalAttribute.

A TSharedAttribute requires at least eight bytes (depending on the platform): four for the vtable and another four for a pointer to the corresponding TInternalAttribute. In addition, a TInternalAttribute requires another four bytes for its vtable, plus the actual data that is shared. The overhead for the vtable in the TSharedAttribute can be factored out, because all attributes that descend from TAttribute pay this cost. The additional cost, therefore, is at least eight bytes (the pointer to the internal attribute plus the vtable for the TInternalAttribute). If the data for any given attribute fits into eight bytes or less, you might not want to use the sharing mechanism.

Reducing extra initialization with Finalize

When the attribute manager is given a new internal attribute instance, and one with the same name and value already exists, it deletes the new internal attribute. If one does not already exist, it calls the virtual member function Finalize on the new attribute. You can use this to delay any expensive attribute initialization that normally would occur in the constructor until Finalize is called, and so avoid this cost for those internal attributes that will just be immediately deleted by the manager.

Making global attributes

You can declare non-internal attributes to be static, thereby making them global to your program. The following code fragment shows a global variable, gAHugeColorAttribute, of type THugeColorAttribute, that can be derived either from a TAttribute or a TSharedAttribute.

    static THugeColorAttribute gAHugeColorAttribute;
NOTE TInternalAttribute can not be declared static because its storage is managed by the attribute manager.

Multithreading attributes

TAttribute, TSharedAttribute, and TInternalAttribute are not synchronized, and so it is not safe to access instances of these classes from multiple threads. This improves performance, but requires you to perform the synchronization yourself if you do need this ability.

Reducing attribute access time using categories

One way to reduce the time required to access attributes is to use categories. Categories are considered an extension of an attribute's name; you use them to group internal attributes for faster access. To take advantage of this feature, override the member function GetCategory to return a value of your choosing. By default, categories reflect the class name and therefore are unique unless you override GetCategory.

Batching change notification

If you make several changes to a group at one time, you can suppress change notification temporarily by bracketing the changes with calls to BeginChanges and EndChanges. BeginChanges stops change notification from this group and all of its ancestors. EndChanges resumes notification and calls NotifyChanged on the group, regardless of whether changes have actually occurred.

Make sure that the same internal group is the target of both calls, otherwise some groups in the hierarchy might continue to suppress change notification.

Change notification is only sent to the group to which EndChanges is called, as well as to its children. If a parent group of this group changes while change notification is suppressed, its handles are never notified. If the parent hierarchy is broken above the group, EndChanges must be called on the parent above the break in order to resume change notification for the old ancestors of the original group.


[Contents] [Previous] [Next]
Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.

Generated with WebMaker