2012-04-03 11 views
17

Tengo un sitio web donde guardo mucha información. Estoy viendo información conflictiva sobre el almacenamiento de cosas en la caché asp.net.¿Cuál es la forma más eficiente de almacenar/recuperar elementos en asp.net? HttpContext.Cache

Por ejemplo Digamos que tengo esta estructura de datos:

Dictionary<string, List<Car>> mydictionary; 

que podría almacenar todo el asunto con una llave de cadena como "MyDictionary" y luego perforar hacia abajo una vez que saco 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 romper hacia abajo y almacenar cada elemento en mi diccionario separado en la memoria caché (dada la 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 diferentes (dada estoy asumiendo que todo está en la memoria de todos modos?)

+4

Recuerde que los cachés son medios para ahorrar el costo de recrear objetos "caros" frecuentemente utilizados (es decir, el costo de recreación excede el costo del almacenamiento en caché). Si vale la caché, permita que la memoria caché aplique las reglas LRU para maximizar el rendimiento. Al poner todas las entradas en una sola entrada de caché ('MyDictionary') se vence el LRU y se corre el riesgo de perder todo el lote si el caché decide que mantener MyDictionary es menos eficiente que mantener otras entradas. – Will

Respuesta

14

Agregando una respuesta adicional aquí ya que siento que la existente captura el 'qué' pero no el suficiente 'por qué'.

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

Hay mucha lógica en la caché ASP.NET para descubrir qué hacer cuando se encuentra con la presión de la memoria. Al final, necesita expulsar algunos elementos, y debe hacerlo de la manera menos perjudicial posible. Los elementos que elige expulsar dependen en gran medida de si se accedió recientemente. Hay otros factores, como qué indicadores se pasan en el tiempo de almacenamiento en caché. p.ej. puede hacer que un elemento no sea extraíble y nunca será expulsado.

Pero volviendo a la pregunta, si almacena todo el diccionario como un solo elemento, solo está dejando dos opciones para la ASP.Administrador de memoria NET: mantener todo vivo, o matar todo. es decir, usted pierde por completo el beneficio de que sus elementos "calientes" permanezcan en el caché, mientras que los elementos que acaparan la memoria que raramente se acceden son expulsados. En otras palabras, pierde cualquier nivel de granularidad de almacenamiento en caché.

Por supuesto, puede optar por 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 ya que no se coordinará con el resto del sistema.

3

Por el momento, la segunda manera es mejor.

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

Esto, sin mencionar los algoritmos utilizados en la memoria caché para priorizar los elementos más usados ​​(MRU si aún recuerdo).

Le recomiendo que mida la ganancia de rendimiento con esto antes de adoptarlo como la implementación final.

7

Como dices, hay dos opiniones opuestas al respecto.

Lo que realmente se reduce a es que las entradas de la memoria caché probablemente se deben almacenar en el nivel más granular, ya 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 recorre el diccionario, guárdelo a nivel individual.

Por lo tanto, si trata la colección completa como una sola unidad, almacénela como una sola unidad. Si se accede aleatoriamente a la colección y solo se necesitan ciertos elementos a la vez, almacénela en el nivel en el que se trata de una sola unidad.

Cuestiones relacionadas