Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiency of persistence methods for large asp.net cache store

Curious if anyone has opinions on which method would be better suited for asp.net caching. Option one, have fewer items in the cache which are more complex, or many items which are less complex.

For sake of discussion lets imagine my site has SalesPerson and Customer objects. These are pretty simple classes but I don’t want to be chatty with the database so I want to lazy load them into cache and invalidate them out of the cache when I make a change – simple enough.

Option 1 Create Dictionary and cache the entire dictionary. When I need to load an instance of a SalesPerson from the cache I get out the Dictionary and perform a normal key lookup against the Dictionary.

Option 2 Prefix the key of each item and store it directly in the asp.net cache. For example every SalesPerson instance in the cache would use a composite of the prefix plus the key for that object so it may look like sp_[guid] and is stored in the asp.net cache and also in the cache are the Customer objects with a key like cust_[guid].

One of my fears with option two is that the numbers of entries will grow very large, between SalesPerson, Customer and a dozen or so other categories I might have 25K items in cache and highly repetitive lookups for something like a string resource that I am using in several places might pay a penalty while the code looks through the cache’s key collection to find it amongst the other 25K.

I am sure at some point there is a diminishing return here on storing too many items in the cache but I am curious as to opinions on these matters.

like image 584
keithwarren7 Avatar asked Jan 06 '09 03:01

keithwarren7


People also ask

How does MemoryCache work C#?

In-Memory Cache is used for when you want to implement cache in a single process. When the process dies, the cache dies with it. If you're running the same process on several servers, you will have a separate cache for each server. Persistent in-process Cache is when you back up your cache outside of process memory.

What is IDistributedCache?

The IDistributedCache interface provides the following methods to manipulate items in the distributed cache implementation: Get, GetAsync: Accepts a string key and retrieves a cached item as a byte[] array if found in the cache. Set, SetAsync: Adds an item (as byte[] array) to the cache using a string key.


2 Answers

You are best off to create many, smaller items in the cache than to create fewer, larger items. Here is the reasoning:

1) If your data is small, then the number of items in the cache will be relatively small and it won't make any difference. Fetching single entities from the cache is easier than fetching a dictionary and then fetching an item from that dictionary, too.

2) Once your data grows large, the cache may be used to manage the data in an intelligent fashion. The HttpRuntime.Cache object makes use of a Least Recently Used (LRU) algorithm to determine which items in the cache to expire. If you have only a small number of highly used items in the cache, this algorithm will be useless. However, if you have many smaller items in the cache, but 90% of them are not in use at any given moment (very common usage heuristic), then the LRU algorithm can ensure that those items that are seeing active use remain in the cache while evicting less-used items to ensure sufficient room remains for the used ones.

As your application grows, the importance of being able to manage what is in the cache will be most important. Also, I've yet to see any performance degradation from having millions of keys in the cache -- hashtables are extremely fast and if you find issues there it's likely easily solved by altering your naming conventions for your cache keys to optimize them for use as hashtable keys.

like image 60
ssmith Avatar answered Sep 21 '22 22:09

ssmith


The ASP.NET Cache uses its own dictionary so using its dictionary to locate your dictionary to do lookups to retrieve your objects seems less than optimal. Dictionaries use hash tables which is about the most efficient lookup you can do. Using your own dictionaries would just add more overhead, I think. I don't know about diminishing returns in regards to hash tables, but I think it would be in terms of storage size, not lookup time.

I would concern yourself with whatever makes your job easier. If having the Cache more organized will make your app easier to understand, debug, extend and maintain then I would do it. If it makes those things more complex then I would not do it.

And as nullvoid mentioned, this is all assuming you've already explored the larger implications of caching, which involve gauging the performance gains vs. the performance hit. You're talking about storing lots and lots of objects, and this implies lots of cache traffic. I would only store something in the cache that you can measure a performance gain from doing so.

like image 35
sliderhouserules Avatar answered Sep 18 '22 22:09

sliderhouserules