asp.net asp.net-mvc caching httpcontext.cache

¿Cuál es la forma más eficiente de almacenar/recuperar elementos en asp.net httpContext.Cache?



asp.net-mvc caching (3)

Tengo un sitio web donde caché mucha información. Estoy viendo información conflictiva sobre el almacenamiento de cosas en el caché de asp.net.

Por ejemplo, digamos que tengo esta estructura de datos:

Dictionary<string, List<Car>> mydictionary;

Podría almacenar todo con una clave de cadena como "MiDiccionario" y luego profundizar una vez que saque el objeto.

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>>;

La otra cosa que podría hacer es descomponerlo y almacenar cada elemento en mi diccionario por separado en el caché (dado que el caché es un diccionario de todos modos).

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>;

¿Sería la implicación de rendimiento muy diferente (dado que supongo que todo está en la memoria de todos modos?)


Como dices, hay dos opiniones opuestas sobre esto.

Lo que realmente se reduce a es que las entradas de caché probablemente deberían almacenarse en el nivel más granular a medida que se necesitan. Con eso, quiero decir, si usa cada entrada en su Diccionario cada vez que se usa, entonces guárdela en el nivel del diccionario.

Si solo usa un elemento del diccionario y no lo lee, entonces guárdelo a nivel individual.

Entonces, si trata a toda la colección como una sola unidad, entonces córtela como una sola unidad. Si se accede a la colección de manera aleatoria y solo se necesitan ciertos elementos a la vez, entonces guárdelos en el nivel en el que es una sola unidad.


Por mucho, la segunda forma es mejor.

Piense en tener que considerar muchos objetos. Cada vez que tenga que obtener 1 valor, solo necesitará obtenerlo, en lugar de tomar el diccionario entyre y, a partir de eso, obtener lo que desea.

Esto no explica los algoritmos utilizados en el caché para priorizar los elementos más utilizados (MRU, si aún lo recuerdo).

Solo te recomiendo que midas la ganancia de rendimiento con esto antes de adoptarla como la implementación final.


Agregando una respuesta adicional aquí, creo que la existente captura el ''qué'' pero no lo suficiente del ''por qué''.

La razón por la que es mejor almacenar las entradas individuales por separado en el caché tiene poco que ver con el rendimiento. En cambio, tiene que ver con permitir que el sistema realice la administración de memoria adecuada.

Hay mucha lógica en el caché de ASP.NET para averiguar qué hacer cuando se ejecuta en la presión de la memoria. Al final, debe expulsar algunos elementos, y debe hacerlo de la manera menos disruptiva posible. Los elementos que elija para expulsar dependen mucho de si se accedió recientemente. Hay otros factores, como los indicadores que se pasan en el momento del almacenamiento en caché. por ejemplo, puede hacer que un artículo no sea removible, y nunca será expulsado.

Pero volviendo a la pregunta, si almacena todo su diccionario como un solo elemento, solo está dejando dos opciones al administrador de memoria ASP.NET: mantener vivo todo el asunto o eliminarlo todo. es decir, usted pierde completamente el beneficio de tener sus elementos ''calientes'' en el caché, mientras que los elementos que acaban de acceder a la memoria son expulsados. En otras palabras, se pierde cualquier nivel de granularidad de almacenamiento en caché.

Por supuesto, puede elegir implementar su propio esquema en su diccionario para eliminar elementos que rara vez se utilizan. Pero en ese momento está reinventando la rueda, y su nueva rueda no funcionará tan bien como no coordinará con el resto del sistema.