Anne-Christine
Anne-Christine

Reputation: 55

Optimize objects with variably needed properties

My application manipulates objects containing many properties, some of them being light and others heavier (require calculations, db queries). In some contexts, I need access to all the properties, and in other contexts (such as gridviews, or when the object is used as a member of another object), I only need access to a few properties.

I already delay the loading of heavy members as late as possible but I don't know how to proceed to avoid 'carrying' properties that I don't need.

I was told to create an additional 'light' version of each class to respond to this issue but my application contains more than 50 classes so it takes a lot of time to do so. Besides, having multiple versions of the same class also generates other issues.

Which solution is the more optimized ? Does it make sense to create multiple class versions ? What if unneeded properties just remain null ? Is an object with null (unassigned) properties heavier than the same without these properties ?

Many thanks for your answers !

Upvotes: 2

Views: 187

Answers (2)

MEverett
MEverett

Reputation: 111

I'm not sure it will help you specifically with your problem, but .NET 4.0 introduced the Lazy class which is a wrapper class used to lazy-initialize heavy/large object instances. It offers a .Value property which when accessed for the first time (and only the first time) initializes the wrapped object instance. If .Value is never accessed, the object instance being wrapped is never initialized. But it sounds like you are already doing this yourself, most likely in your property Get/Set definition.

In terms of which object is heavier, a light-weight class without the properties or the original class with NULL variables: If the properties in questions are reference types then the only wastage is for the pointer to the reference type which is either 4 bytes per property for x86 and 8 bytes per property for x64. The default minimum size of an empty class instance in .NET appears to be around ~24 bytes.

For example:

public class MyClassLight
{
    public int PropertyInt { get; set; } // 4 byte value type
    public OtherClass1 PropertyOtherClass1 { get; set; } // 4 or 8 byte reference type
}

public class MyClassHeavy
{
    public int PropertyInt { get; set; } // 4 byte value type
    public string PropertyString { get; set; } // 4 or 8 byte reference type
    public OtherClass1 PropertyOtherClass1 { get; set; } // 4 or 8 byte reference type
    public OtherClass2 PropertyOtherClass2 { get; set; } // 4 or 8 byte reference type
}

Let's say you were running on x86 an instance of the MyClassLight would cost 24 bytes overhead + 4 bytes + 4 bytes = 32 bytes of memory.

MyClassHeavy would be 24 bytes overhead + 4 bytes + 4 bytes + 4 bytes + 4 bytes = 40 bytes of memory.

Even if your heavy class had 50 properties that were reference types, keeping them NULL would only incur an extra 200 bytes of memory per instance (because the class still needs to reserve the memory for the pointers, which might be used at some point). If you have hundreds of thousands or millions of these objects in memory 200 bytes per object might be a concern, but if not it seems negligible.

The added complexity of having 2 versions of 50 classes does not seem worth it. But if you have to go that route I would refactor it to create an interface that included only the properties that both classes (light and heavy) share and then refactor code to use the interface instead of the concrete class as much as possible so it's compatible with both light and heavy classes.

Upvotes: 1

Alok
Alok

Reputation: 274

May be you can create counstructor to initialize only light properties. And have lazy initialization of heavy properties( initialize only when accessed). Then you can have a light weight object which will ofcourse have all the properties but not initialized.

Upvotes: 0

Related Questions