Подтвердить что ты не робот

Каков наиболее эффективный способ хранения/извлечения элементов в asp.net 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>;

Было бы очень сильно отличаться представление производительности (учитывая, что я предполагаю, что все равно в памяти?)

4b9b3361

Ответ 1

Добавление дополнительного ответа здесь, поскольку я чувствую, что существующее фиксирует "что", но недостаточно "почему".

Причина, по которой лучше хранить отдельные записи отдельно в кеше, имеет мало общего с перфомансом. Вместо этого это связано с тем, что система может выполнять правильное управление памятью.

В кеше ASP.NET существует много логики, чтобы выяснить, что делать, когда она сталкивается с давлением памяти. В конце концов, ему нужно выталкивать некоторые предметы, и это нужно сделать наименее разрушительным способом. Какие элементы, которые он выбрал для выключения, зависят от того, были ли они недавно получены. Существуют и другие факторы, например, какие флаги передаются во время кэширования. например вы можете сделать элемент несъемным, и его никогда не выбьют.

Но, возвращаясь к вопросу, если вы сохраняете весь словарь в виде одного элемента, вы оставляете только два варианта диспетчера памяти ASP.NET: держите все в живых или убивайте все это. т.е. вы полностью теряете выгоду от того, чтобы ваши "горячие" элементы оставались в кеше, в то время как ваши редко доступные объекты для хранения памяти выбиваются из игры. Другими словами, вы теряете любой уровень кеширования.

Конечно, вы могли бы реализовать свою собственную схему в своем словаре, чтобы удалить элементы, которые редко используются. Но в этот момент вы изобретаете колесо, и ваше новое колесо не будет работать, так как оно не будет координировать работу с остальной системой.

Ответ 2

Как вы говорите, есть два противоположных мнения по этому поводу.

На самом деле это сводится к тому, что записи кэша, вероятно, должны храниться на самом узком уровне по мере необходимости. Под этим я имею в виду, что если вы используете каждую запись в своем словаре каждый раз, когда она используется, сохраните ее на уровне словаря.

Если вы используете только один элемент из словаря, и вы не ходите по словарю, а затем храните его на отдельном уровне.

Итак, если вы обрабатываете всю коллекцию как единое целое, то кешируйте ее как единое целое. Если коллекция случайным образом доступна, и только определенные элементы необходимы за раз, а затем сохраните ее на уровне, на котором он является единственным элементом.

Ответ 3

Скорее всего, второй способ лучше.

Подумайте, стоит ли рассматривать многие объекты. Каждый раз, когда вам нужно получить 1 значение, вам нужно будет только его получить, вместо того, чтобы захватывать словарь энтира и, из этого, получить то, что вы хотите.

Это, не говоря о алгоритмах, используемых в кеше, для определения приоритетности наиболее используемых элементов (MRU, если я все еще помню).

Я просто рекомендую вам измерить прирост производительности с этим, прежде чем принимать его в качестве окончательной реализации.