在asp.net httpContext.Cache中存储/检索项目的最有效方法是什么

时间:2012-04-03 13:02:23

标签: asp.net asp.net-mvc caching httpcontext.cache

我有一个网站,我可以缓存很多信息。我看到有关在asp.net缓存中存储内容的相互矛盾的信息。

例如,假设我有这样的数据结构:

 Dictionary<string, List<Car>> mydictionary;

我可以使用字符串键将整个事物存储为“MyDictionary”,然后在我拉出对象时向下钻取。

 HttpContext.Cache.Add("MyDictionary",  
   mydictionary, 
   null, 
   Cache.NoAbsoluteExpiration,
   new TimeSpan(10, 0, 0),
   CacheItemPriority.Normal,
   null);

 var myDict = HttpContext.Cache["MyDictionary"] as Dictionary<string, List<Car>>;

我能做的另一件事是将其分解并将每个项目分别存储在我的字典中的缓存中(假设缓存是字典)。

 Dictionary<string, List<Car>> mydictionary;

 foreach (var item in mydictionary.Keys)
 {
      HttpContext.Cache.Add(item, mydictionary[item], null, Cache.NoAbsoluteExpiration, new TimeSpan(10, 0, 0), CacheItemPriority.Normal, null);
 }

 var myitem = "test";
 var myDict = HttpContext.Cache[myItem] as List<Car>;

性能含义是否会非常不同(假设我假设一切都在内存中?)

3 个答案:

答案 0 :(得分:14)

在这里添加一个额外的答案,因为我觉得现有的答案会捕捉'为什么'而不是'为什么'。

最好将各个条目分别存储在缓存中与perf几乎没有关系。相反,它与允许系统执行适当的内存管理有关。

ASP.NET缓存中有很多逻辑可以确定在遇到内存压力时要做什么。最后,它需要踢出一些项目,它需要以最少的破坏性方式做到这一点。它选择推出哪些项目取决于他们最近是否被访问过。还有其他因素,例如在缓存时传递的标志。例如你可以让一件物品不可拆卸,而且永远不会被踢掉。

但回到这个问题,如果你将整个字典存储为单个项目,那么你只需要为ASP.NET内存管理器留下两个选项:保持整个事物的存活,或者杀死整个事物。也就是说,你完全失去了让你的“热门”物品留在缓存中的好处,而你很少被访问的内存占用物品被淘汰出局。换句话说,您将失去任何级别的缓存粒度。

当然,您可以选择在字典中实现自己的方案,以删除很少使用的项目。但是那时你正在重新发明轮子,而你的新轮子将无法正常工作,因为它不会与系统的其他部分协调。

答案 1 :(得分:7)

正如你所说,对此有两种反对意见。

它真正归结为的是,缓存条目可能应该在需要时以最精细的级别存储。我的意思是,如果你每次使用它时都使用你的词典中的每个条目,那么将它存储在字典级别。

如果您只使用字典中的一个项目,并且不走字典,则将它们存储在单个级别。

因此,如果您将整个集合视为一个单元,则将其作为一个单元进行缓存。如果随机访问该集合,并且一次只需要某些项目,则将其存储在单个单元的级别。

答案 2 :(得分:3)

到目前为止,第二种方式更好。

考虑必须考虑许多对象。每次你必须得到1个值,你只需要得到它,而不是抓住entyre字典,从中得到你想要的。

这不是关于缓存中使用的算法来确定最常用项目的优先级(MRU,如果我还记得)。

我建议您在将其作为最终实现之前使用它来衡量性能提升。