【问题标题】:Is there a difference between caching IEnumerable or IList in HttpRuntime cache?在 HttpRuntime 缓存中缓存 IEnumerable 或 IList 有区别吗?
【发布时间】:2018-06-27 21:05:46
【问题描述】:

假设下面这段代码缓存了两个对象集合MyObject:一个集合是IEnumerable<MyObject>类型,另一个是List<MyObject>类型。代码从缓存中检索值,然后访问集合:

class Program
{
    static void Main(string[] args)
    {
        CacheManager.CacheSomething();
    }

    public class MyService
    {
        private IEnumerable<AnObject> AnObjects
        {
            get
            {
                return new[]
                {
                    new AnObject {MyString1 = "one", MyString2 = "two"},
                    new AnObject {MyString1 = "three", MyString2 = "four"}
                };
            }
        }

        public IEnumerable<AnObject> GetEnumerable()
        {
            return AnObjects;
        }

        public List<AnObject> GetList()
        {
            // Run it out to a list
            return AnObjects.ToList();
        }
    }

    public static class CacheManager
    {
        public static void CacheSomething()
        {
            // Get service
            var service = new MyService();

            // Get the values as List and Enumerable
            var list = service.GetList();
            var enumerable = service.GetEnumerable();

            // Putting them in a cache
            HttpRuntime.Cache.Insert("list", list);
            HttpRuntime.Cache.Insert("enumerable", enumerable);

            // Get the values
            var retrievedList = HttpRuntime.Cache["list"] as List<AnObject>;
            var retrievedEnumerable = HttpRuntime.Cache["enumerable"] as IEnumerable<AnObject>;

            // Access both
            var res1 = retrievedList.ToList();
            var res2 = retrievedEnumerable.ToList();               
        }
    }

    public class AnObject
    {
        public string MyString1 { get; set; }
        public string MyString2 { get; set; }
    }
}

根据集合类型存储这些对象所需的内存量是否存在差异?

我问的原因是,当我们分析我们的应用程序时,我们注意到当我们查看依赖关系树时,IEnumerable 具有与之关联的服务。这是否意味着它也会缓存服务?

谁能说明这是否值得关注?在缓存中存储IEnumerable 是否有问题?我们是否应该更喜欢缓存Lists 而不是IEnumerables?

【问题讨论】:

  • 如果您已经完成了所有这些的编写过程,为什么不更进一步,使用基准工具查看两者的性能以及它们的分配情况?
  • 我刚刚花了我一天中最好的时间来调查这个问题,但我仍然没有具体的答案。想要证明这一点比您想象的要难。

标签: c# list caching ienumerable httpruntime.cache


【解决方案1】:

内存量不同?没有。

为什么? IEnumerable 不是类型;这是一个界面。这意味着存储在IEnumerable 中的任何内容实际上都是实现IEnumerable 的其他类型(例如List)。

IEnumerable 只强制实现读取列表的方法。它不适合修改集合。这就是为什么您希望将其转换为实际类型(例如List),因此您可以使用类似Add 的方法。

【讨论】:

  • 谢谢。因此,就内存使用而言,如果正如@nvoigt 所说,在被问及存储数据的承诺时,如果它本身不存储数据,那么我认为它在内存占用方面可能会有所不同? (指向数据承诺的指针与将实际物化数据存储在缓存中不同?)感谢您的时间和知识。
【解决方案2】:

IEnumerable不是数据。这是一个承诺,当您询问时,您将收到数据。有些数据可能会实现它(数组、列表),但有时,它不是物化数据,而是对数据库的查询。

“缓存”您的IEnumerable 意味着您缓存从何处获取 数据的知识。那不是你想要的。您想要缓存数据本身

始终在缓存结果之前实现您的IEnumerables(例如使用 ToList 或 ToArray)。否则,您最终可能会得到一个缓存,其中仅包含一个为获取数据而调用的过程。


您示例中的IEnumerable 仍然持有对服务的引用的事实正是:它不持有数据,它持有对服务的引用并将调用再次使用它时。所以与你想要从缓存中得到的完全相反。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 2017-07-15
    • 2011-04-11
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多