Property caching strategy.

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?
 
J

Jeroen van Langen

??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?
 
A

Arne Vajhøj

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top