Calculated Properties

Calculated Properties

Old forum URL: forums.lhotka.net/forums/t/10966.aspx


xal posted on Thursday, December 08, 2011

Here's a little demo app I just wrote.

It only shows the size of the object graph after serialization, with and without calculated properties.

It does not test:

-Serialization times

-Deserialization times

-Dataportal fetch times

All of these will be slower without calculated properties. In the first two cases because there is more data to serialize and deserialize and in the last case because the values need to be calculated on the server.

This is just the most basic example. I did not take the time to create the rules to calculate those values, I'm just getting them from the first collection.

 

For the data that is generated for this example, it shows that not using calculated properties implies a 66% increase memory use, if we serialize data to a memory stream. Again, I want to stress that this is just for this data, it could be more, it could be less depending on the number of properties, their types, and the lengths of the strings. But regardless, not using calculated properties will always take more time and memory.

 

Andrés

RockfordLhotka replied on Thursday, December 08, 2011

Try making the calculated property value a private non-serialized field to eliminate the serialization overhead.

edore replied on Thursday, December 08, 2011

The problem with properties with private backing fields is you can't set the value in a rule using AddOutValue().  Am I right?  Or I may have misunderstood something...

JonnyBee replied on Saturday, December 10, 2011

edore

The problem with properties with private backing fields is you can't set the value in a rule using AddOutValue().  Am I right?  Or I may have misunderstood something...

That's a misunderstanding.

But the RuleEngine has no knowledge of how to set the private field so you - the developer - must override the business object non-generic LoadProperty (that is called by the rule engine) to set the private field.

ex:

    public static readonly PropertyInfo<string> MyPrivateFieldProperty = RegisterProperty<string>(c => c.MyPrivateField, RelationshipTypes.PrivateField);
 
    // [NotUndoable, NonSerialized]
    private string _privateValue = MyPrivateFieldProperty.DefaultValue;
    public string MyPrivateField
    {
      get { return GetProperty(MyPrivateFieldProperty, _privateValue); }
      set { SetProperty(MyPrivateFieldProperty, ref _privateValue, value); }
    }
 
    protected override void LoadProperty(Csla.Core.IPropertyInfo propertyInfo, object newValue)
    {
      if (propertyInfo == MyPrivateFieldProperty)
      {
        _privateValue = (string)newValue;
      }
      else base.LoadProperty(propertyInfo, newValue);
    }

Will allow you to use the AddOutValue in a BusinessRule for the MyPrivateField private backing field.

edore replied on Monday, December 12, 2011

Hi Jonny,

I already knew this "hack" and it's certainly not something I want to do everytime I need to set a property with private backing field.  It's annoying and leads to quite ugly code if you have have a couple properties like that. 

So to me, calculated properties with private backing fields are not a good solution, and calculated properties with managed backing fields aren't either because they contribute to the metastate of the BO, which is wrong IMHO.  Memory and serialization overhead aren't my main concern at the moment, I feel the mobile formatter improvements will help us reduce this overhead...

I'm looking forward for the elimination of the private backing fields but I hope the replacement will take metastate into account.

xal replied on Thursday, December 08, 2011

Yes, that would work around the serialization problem. But you keep the memory overhead anyway. You also end up processing the rules twice -on client and server-, thus doubling the cpu overhead. The point of this it to keep the server light and fast. If those properties are calculated and are never read, they will never incur any overhead. With that solution they will.

The first implementation I made declares the propertyinfo object using PrivateField, but there really is no private field because the property is just a calculation based on another.

Are you trying to say that calculated properties are wrong or bad? I think there's a big difference between a business rule and a calculated property, and rules are not adequate for this situation. If you have a datetime property, but also want to expose the time and date parts separately in another 2 properties, it makes no sense to store those values separately. Think about SmartDate, would you change it's implementation to have a field for the date and another one for the string and yet another for DBValue? Then you'd have to create a rule for when the dateformat changes. And the same for the date, text and DBValue properties. And you'd also have to keep up with all of them and always keep an eye out for somebody writing code that sets those fields directly. Do you really think that is the best way to go?

On the other hand, I suggested various improvements for private fields and in another post I was basically told not to use them bacause they were going away when the new serializer comes. So what is it really? is support for private fields going to be discontinued completely?

Copyright (c) Marimer LLC