AppFabric / NCache - will these HttpRuntime.Cache objects be updated by reference?

When using HttpRuntime.Cache in an ASP.NET application, any item received from the cache, which is then updated, will also update the cached object (by reference). Subsequent reads from the cache will receive an updated value, which may be undesirable.

There are several posts on this subject, for example:

Read the HttpRuntime.Cache Element as Read Only

And the proposed solution is to create a deep copy clone using binary serialization.

The problem with binary serialization is that it is slow (incredibly slow) and I cannot afford any potential performance bottlenecks. I looked at deep copying using reflection, and although this seems to work better, it is not trivial to implement with our complex DTOs. Anyone interested in this might want to take a look at the following short article:

Fast deep cloning

Does anyone have any experience caching solutions like AppFrabric / NCache, etc., and know if they can solve this problem directly?

Thanks in advance

Griff

0
source share
2 answers

Products such as NCache and AppFabric also serialize before storing the object in the cache service outside the process. Thus, you still take this serialization hit, plus you slow down even more when you exit the process (or perhaps even over the network) to access the serialized object in the caching service.

Implementing ICloneable in your classes for manual deep-copying will avoid reflection and outperform binary serialization, but this may not be the case if your DTOs are very complex.

Updated to provide specifics:

AppFabric usese NetDataContractSerializer for serialization (as described here ). NetDataContractSerializer may be slightly faster than BinaryFormatter, but its performance is usually in the same ball: http://blogs.msdn.com/b/youssefm/archive/2009/07/10/comparing-the-performance-of -net-serializers.aspx

NCache has deployed its own serializer called Compact Serialization. You need to either implement your ICompactSerializable interface in your DTO classes, either manually read all the records, or let their client libraries examine your class and then issue your own serialization code at run time to do the job for you (this is a one-time version when your the application starts where they should reflect your class and issue their own MSIL). I have no data on their performance, but I can safely assume that it is faster than serializers that perform reflection (BinaryFormatter / DataContractSerializer) and probably somewhere in the same performance area as protobuf, MessagePack and other serializers that avoid excessive reflection. More details here .

(I work for a company (ScaleOut Software), which is in the same space as NCache, so I probably should know more about how they do it. ScaleOut allows you to plug in any serializer you want - we usually recommend Protobuf-net or MessagePack , as they are usually considered reigning champions for .NET serialization performance - be sure to look carefully at these two if you decide to use the serializer to create your deep copies.)

+4
source

Most cache systems rely on serialization.

You must consider the invalidation of the cache every time the object changes.

For example:

object Get(string key) { if (!Cache.Contains(key)) { Cache[key] = GetDataFromDatabase(key); } return Cache[key]; } void Invalidate(string key) { Cache.Remove(key); } 

So you can do:

 var myDto = Get(id); myDto.SomeProperty = "changed"; myDto.Save(); Invalidate(id); 
0
source

All Articles