【问题标题】:What is the most efficient way to store / retrieve items in asp.net httpContext.Cache在 asp.net httpContext.Cache 中存储/检索项目的最有效方法是什么
【发布时间】:2012-04-17 03:23:12
【问题描述】:

我有一个网站,我缓存了很多信息。我看到有关在 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>;

性能影响会非常不同(假设我假设一切都在内存中?)

【问题讨论】:

  • 请记住,缓存是节省重新创建经常使用的expensive 对象成本的手段(即,重新创建的成本超过缓存的成本)。如果值得缓存,请允许缓存应用 LRU 规则以最大限度地提高性能。将所有条目放入单个缓存条目(“MyDictionary”)会破坏 LRU,并且如果缓存认为保留 MyDictionary 的效率低于保留其他条目的效率,则可能会丢失全部内容。

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


【解决方案1】:

在这里添加一个额外的答案,因为我觉得现有的答案捕捉到了“是什么”,但没有足够的“为什么”。

最好将单个条目单独存储在缓存中的原因与性能无关。相反,它与允许系统执行适当的内存管理有关。

ASP.NET 缓存中有很多逻辑来确定遇到内存压力时该怎么办。最后,它需要踢出一些项目,并且需要以尽可能少的破坏性方式执行此操作。它选择踢出哪些项目很大程度上取决于它们最近是否被访问过。还有其他因素,例如在缓存时传递的标志。例如你可以让一个项目不可移动,它永远不会被踢出。

但是回到这个问题,如果您将整个字典存储为单个项目,那么您只给 ASP.NET 内存管理器留下了两个选项:保持整个内容处于活动状态,或者杀死整个内容。即,您完全失去了将“热门”项目保留在缓存中的好处,而您很少访问的占用内存的项目则被踢出。换句话说,您会丢失任何级别的缓存粒度。

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      我只是建议您在将其作为最终实现之前衡量性能增益。

      【讨论】:

        猜你喜欢
        • 2014-05-14
        • 2013-07-04
        • 2011-02-26
        • 2021-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-15
        相关资源
        最近更新 更多