Property caching strategy.

  • Thread starter Thread starter Sin Jeong-hun
  • Start date Start date
S

Sin Jeong-hun

I sometimes use the following caching scheme in order to save
unnecessary CPU usage.
class SampleClass
{
LargeClass _SampleProperty;
public LargeClass SampleProperty
{
get
{
if(_SampleProperty == null)
{
_SampleProperty = DoSomeCostlyOperation();
}
return _SampleProperty;
}
}

I think you may do the same, probably. The problem is the
_SampleProperty is kept for ever until the SampleClass instance is
destroyed, and it is acceptable that _SampleProperty is deleted.
Because if it becomes null, it can always be recreated on demand. This
scheme looks like a little bit waste. Of course, I can create my own
scheme to remove the cached _SampleProperty. For example, set a timer
in the SampleClass, so if 10 minutes have passed since the last access
of SampleProperty, it will delete _SampleProperty. But that may not be
efficient.

Is there any proven, widely used strategy for this thing? Or you just
don't care about the cached properties?
 
??Hi,

The only offence to this method is, you can't predict when the LargeClass is
constructed. So this is just 1 part of the solution.
What if the CostlyOperation uses other properties? The _SampleProperty must
be invalidated when other properties changes.

public SampleClass
{
private bool _isDirty = true;
private LargeClass _SampleProperty;

public LargeClass SampleProperty
{
get
{
if(_isDirty)
{
_SampleProperty = DoSomeCostlyOperation();
_isDirty = false;
}
return _SampleProperty;
}
}

public double OtherProperty
{
get { return _otherProperty; }
set
{
if(value != _otherProperty)
{
_otherProperty = value;
_isDirty = true;
}
}
}
}


If the _SampleProperty doesn't depend on other properties. Why do the
CostlyOperation each instance of the class? You can construct it ones.
(static)

public SampleClass
{
private static LargeClass _SamplePropertyStatic =
DoSomeCostlyOperation();

public LargeClass SampleProperty
{
get
{
return _SamplePropertyStatic;
}
}
}

So this solution isn't that bad, but you should extend it.


About a timer to clean it up. What if you have about 10k instances. You'll
check all instances for last access? I think this would give a bigger
overhead than not caching it.
Alternative solution could be the use of a WeakReferences. So the garbage
collector will decide if the memory is released.

class SampleClass
{
WeakReference _SampleProperty = new WeakReference(null); //LargeClass

public LargeClass SampleProperty
{
get
{
LargeClass result;
if(!_SampleProperty.IsAlive)
{
result = DoSomeCostlyOperation();
_SampleProperty = new WeakReference(result);
}
else
result = (LargeClass )_SampleProperty.Target;

return result;
}
}
}

http://msdn.microsoft.com/en-us/library/system.weakreference.aspx

Regards,
Jeroen







"Sin Jeong-hun" schreef in bericht

I sometimes use the following caching scheme in order to save
unnecessary CPU usage.
class SampleClass
{
LargeClass _SampleProperty;
public LargeClass SampleProperty
{
get
{
if(_SampleProperty == null)
{
_SampleProperty = DoSomeCostlyOperation();
}
return _SampleProperty;
}
}

I think you may do the same, probably. The problem is the
_SampleProperty is kept for ever until the SampleClass instance is
destroyed, and it is acceptable that _SampleProperty is deleted.
Because if it becomes null, it can always be recreated on demand. This
scheme looks like a little bit waste. Of course, I can create my own
scheme to remove the cached _SampleProperty. For example, set a timer
in the SampleClass, so if 10 minutes have passed since the last access
of SampleProperty, it will delete _SampleProperty. But that may not be
efficient.

Is there any proven, widely used strategy for this thing? Or you just
don't care about the cached properties?
 
I sometimes use the following caching scheme in order to save
unnecessary CPU usage.
class SampleClass
{
LargeClass _SampleProperty;
public LargeClass SampleProperty
{
get
{
if(_SampleProperty == null)
{
_SampleProperty = DoSomeCostlyOperation();
}
return _SampleProperty;
}
}

I think you may do the same, probably. The problem is the
_SampleProperty is kept for ever until the SampleClass instance is
destroyed, and it is acceptable that _SampleProperty is deleted.
Because if it becomes null, it can always be recreated on demand. This
scheme looks like a little bit waste. Of course, I can create my own
scheme to remove the cached _SampleProperty. For example, set a timer
in the SampleClass, so if 10 minutes have passed since the last access
of SampleProperty, it will delete _SampleProperty. But that may not be
efficient.

Is there any proven, widely used strategy for this thing? Or you just
don't care about the cached properties?

I am pretty sure that in 99% of cases people initialize and
then keep the property value around for the lifetime
of the object.

If you for some reason only want to keep it around for N minutes,
then you should look at some prebuilt cache with expiration
library.

If you happens to be on .NET 4.0, then you don't need to
search much:

http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx

For earlier .NET versions the same functionality exists for
ASP.NET web apps.

Arne
 
Back
Top