2009-08-05 24 views
15

Bazı örnek kodlara bakıyordum ve küçük bir miktar veriyi depolamak için ListDictionary nesnesi kullandılar (yaklaşık 5-10 nesne vb.), Ancak bu sayı zaman içinde değişebilir). Bu sınıfı kullanmamdaki tek sorun şu ki, yaptığım her şeyden farklı olarak jenerik değil. Bu, eğer burada yanılıyorsam, bir nesneyi her defasında bir noktaya aldığımı ya da üzerinde döküm olduğunu söyleyen her şeyi bulduğumda beni düzeltin ve düzeltin. Genel olmayan bir ListDictionary ek yükünü haklı çıkarmak için daha büyük Dictionary<T> nesnesinde yeterli ek yük var mı?ListDictionary sınıfına genel bir alternatif var mı?

Bu nesneyi kullanacak olan kod, her bir sayfa yükü üzerinde numaralandırılacaktır; tahmin ettiğim, ListDictionary sınıfının diğer alternatiflerden biri üzerinde kullanılmasının nedeni. Bu yüzden bu veri listesinden en yüksek performansı almak istiyorum.

+0

Bunun hakkında bir sonuca varıp performans ölçümü yaptınız mı? Koleksiyonda sadece bir avuç dolusu öğe olduğunda, her zaman bir 'Sözlük 'kullanarak beni rahatsız ediyor, ancak orada olmanın rahatlığı her zaman başka bir şey seçme veya yazma ile ilgili rahatsızlık/riskten daha ağır basıyordu. Performans açısından değil, büyük bir anlaşma değil. – Rory

cevap

10

Maalesef, ListDictionary genel eşdeğeri yoktur. Bununla birlikte, birini uygulamak çok zor olmamalıdır. ListDictionary, temel olarak, Anahtar/Değer çiftlerinin bağlantılı listesini tutarak ve arama işlemleri için bunları yineleyerek çalışır. Bazı çok basit LINQ ifadeleriyle LinkedList<T>'u sarmak suretiyle ListDictionary<TKey,TValue> oluşturabilirsiniz. Örneğin

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

LINQ kullanarak Hash Codes hesaplamak çok pahalı olmadıkça bir ListDictionary kullanarak hemen hemen tüm performans yararlarını olumsuz etkileyeceğini hayal ediyorum. – Chuu

+0

@Chuu Ama ListDictionary zaten değerlere erişirken her bir tuşa eşittir, bu yüzden neden LINQ'ları sağlayın Performans üzerinde olumsuz bir etkisi var mı? – sluki

+1

@sluki Nesne atamaları ve delege çağrıları için bir for döngüsü içeren tek bir yöntem. LINQ, çerçeve kodu için okunabilir değildir. – jnm2

4

ListDictionary içinde sakladığınız veriler, değer türleri yerine her zaman nesneler (sınıflar) ise, muhtemelen <T> Dictionary'den daha hızlı olacaktır. Eğer değer türlerini (struct, int, double, vb.) Depolayacaksanız, o zaman boks/kutuklama maliyeti büyük olasılıkla şeyleri dengeleyecektir ve bunun yerine Dictionary <T>'u tavsiye ederim. Bununla birlikte, genel olarak, bu ikisi arasındaki performans farkının genel olarak performans sorunlarınızdan en az biri olabileceğini belirtmek isterim. Bunun gibi küçük şeyler genellikle performans optimizasyonu söz konusu olduğunda endişelenecek son şeydir. İşlemler arası çağrılar, veritabanı ve web hizmeti etkileşimi, vb. Gibi daha büyük ölçekli şeyler, ListDictionary ve Dictionary <T> arasındaki küçük performans farkından endişelenmeden önce ele alınmalıdır.

+0

Performans açısından endişelenecek daha büyük şeyler olduğunu kesinlikle kabul ediyorum. Bunu sormamın sebebi şu anda baktığım ve şimdi projeye eklediğim bir şey. Bu yüzden ListDictionary sınıfına daha iyi bir alternatif kullanabiliyorsam, o zaman bunu olduğu gibi bırakmaktan daha iyidir. –

1

için

MSDN-ListDictionary sınıfına Basit onay Bu tek başına bağlantılı listesini kullanarak IDictionary basit bir uygulamasıdır

ortaya çıkaracaktır. Eger eleman sayisi 10 veya daha az ise, Hashtable'den daha küçük ve hizlidir. performansı büyük eleman sayısı için önemli ise, bu kullanılmamalıdır.

1

Biz kullanabilirsiniz,

Örnek için
System.Collections.Generic.Dictionary<Object,Object> dictTemp = new System.Collections.Generic.Dictionary<Object,Object>(); 

,

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

bu seni biraz yardımcı olacağını düşünüyorum aşağıdakileri düşünün!

1

ListDictionary genel bir karşılığı yoktur.Bu küçük sözlüğe kullanımınız Add ve Remove hakim değilse

, sen adına rağmen, IDictionary<TKey, TValue> uygulayan SortedList<TKey, TValue> düşünebilirsiniz. Tek tek bağlantılı bir liste tarafından desteklenen ListDictionary'un aksine, SortedList, sıralanmış bir dizi dizi ve bir dizi değeriyle desteklenir.

+0

Bence bu şimdiye kadarki en iyi cevap. –

İlgili konular