2009-08-05 13 views
15

Estaba viendo un código de ejemplo y en él usaban un objeto ListDictionary para almacenar una pequeña cantidad de datos (alrededor de 5-10 objetos más o menos, pero este número podría cambiar con el tiempo). El único problema que tengo con el uso de esta clase es que, a diferencia de todo lo demás que he estado haciendo, no es genérico. Esto significa, y corrígeme si me equivoco aquí, que cada vez que saco un objeto de aquí o que enumero sobre él, está ocurriendo un casting. ¿Hay suficiente sobrecarga en el objeto más grande Dictionary<T> para justificar la sobrecarga de un ListDictionary no genérico?¿Existe una alternativa genérica a la clase ListDictionary?

El código que usará este objeto se enumerará en cada carga de página, lo que supongo es por qué la clase ListDictionary se utilizó sobre una de las otras alternativas. Esta es también la razón por la que me gustaría obtener el máximo rendimiento de esta lista de datos.

+0

¿Llegó a una conclusión al respecto y realizó alguna medición de rendimiento? Siempre me molesta usar un 'Diccionario ' cuando solo haya un puñado de elementos en la colección, pero la conveniencia de que esté ahí siempre ha superado el riesgo/incomodidad asociado con elegir o escribir algo más. No es un gran problema en cuanto a rendimiento ... a menos que lo sea. – Rory

Respuesta

10

Desafortunadamente, no existe un equivalente genérico de ListDictionary.

Sin embargo, no debería ser terriblemente difícil implementar uno. ListDictionary esencialmente funciona manteniendo una lista vinculada de pares Clave/Valor e iterando sobre ellos para las operaciones de búsqueda. Puede construir un ListDictionary<TKey,TValue> al envolver un LinkedList<T> con algunas expresiones LINQ muy simples.

Por ejemplo

public class LinkedDictionary<TKey,TValue> { 
    private LinkedList<KeyValuePair<TKey,TValue>> _list = new LinkedList<KeyValuePair<TKey,TValue>>(); 
    private IEqualityComparer<TKey> _comp = EqualityComparer<TKey>.Default; 

    public void Add(TKey key, TValue value) { 
    _list.Add(new KeyValuePair<TKey,TValue>(key,value)); 
    } 
    public TValue Get(TKey key) { 
    return _list.Where(x => _comp.Equals(x.Key,key)).First().Value; 
    } 
    ... 
} 
+4

Me imagino que usar LINQ negaría casi todos los beneficios de rendimiento de usar un ListDictionary a menos que el cálculo de los códigos Hash fuera terriblemente costoso. – Chuu

+0

@Chuu Pero ListDictionary ya llama Igual a cada tecla al acceder a los valores, entonces, ¿por qué se deben proporcionar los LINQ? ¿Dónde tienen alguna influencia negativa en el rendimiento? – sluki

+1

@sluki Asignaciones de objetos e invocaciones de delegados versus un único método que contiene un ciclo for. LINQ es para legibilidad, no para código de framework. – jnm2

4

Si los datos que está almacenando en el ListDictionary son siempre objetos (clases), en lugar de tipos de valores, entonces probablemente sea más rápido que el diccionario T >. Si va a almacenar tipos de valores (estructuras, int, doble, etc.), el costo del boxeo/unboxing probablemente equilibrará las cosas, y en su lugar recomendaría el Dictionary <T>.

En general, sin embargo, señalaría que la diferencia de rendimiento entre estos dos probablemente sea la menor de sus problemas de rendimiento en general. Pequeñas cosas como esta son generalmente lo último de lo que preocuparse cuando se trata de la optimización del rendimiento. Las cosas de mayor escala, como las llamadas entre procesos, la interacción entre bases de datos y servicios web, etc. deben abordarse antes de preocuparse por la menor diferencia de rendimiento entre ListDictionary y el Diccionario <T>.

+0

Estoy completamente de acuerdo en que hay cosas más importantes de las que preocuparse en términos de rendimiento. El motivo para preguntar esto es que ahora es algo que estoy revisando y agregando al proyecto ahora. Entonces, si puedo usar una mejor alternativa a la clase ListDictionary desde el principio, supongo que es mejor que dejarla tal como está. –

1

una sencilla comprobación de MSDN-ListDictionary clase revelará

Ésta es una implementación sencilla de IDictionary usando una lista enlazada sencilla . Es más pequeño y más rápido que un Hashtable si el número de elementos es 10 o menos. Esto no debe usarse si el rendimiento de es importante para grandes números de elementos .

1

Podemos utilizar,

System.Collections.Generic.Dictionary<Object,Object> dictTemp = new System.Collections.Generic.Dictionary<Object,Object>(); 

Por ejemplo, considere la siguiente,

using System.Collections.Specialized; 

    private ListDictionary g_Attributes = new ListDictionary(); 
    public ListDictionary Attributes 
    { 
     get { return this.g_Attributes; } 
    } 
    public string GetAttribute(string name) 
    { 
     if (HasAttribute(name)) 
      return (string) g_Attributes[name]; 
     else 
      return null; 
    } 
    public bool HasAttribute(string name) 
    { 
     return this.Attributes.Contains(name); 
    } 


    using System.Collection.Generic; 

    private Dictionary<string, object> g_Attributes = new Dictionary<string, object>(); 
    public Dictionary<string, object> Attributes 
    { 
     get { return this.g_Attributes; } 
    } 
    public string GetAttribute(string name) 
    { 
     if (HasAttribute(name)) 
     { 
      return g_Attributes[name].ToString(); 
     } 
     else 
     { 
      return null; 
     } 
    } 
    public bool HasAttribute(string name) 
    { 
    return this.Attributes.ContainsKey(name); 
    } 

creo que esto le ayudará un poco!

1

No existe un equivalente genérico de ListDictionary.

Si el uso de este pequeño diccionario no está dominado por Add y Remove, es posible considerar SortedList<TKey, TValue> que, a pesar de su nombre, implementa IDictionary<TKey, TValue>. A diferencia de ListDictionary que está respaldado por una lista de enlace único, SortedList está respaldado por una matriz de claves ordenadas y valores de una matriz.

+0

Creo que esta es la mejor respuesta hasta el momento. –

Cuestiones relacionadas