2009-08-05 2 views
15

Я искал пример кода, и в нем использовался объект ListDictionary для хранения небольшого количества данных (около 5-10 объектов или около того, но это число со временем может меняться). Единственная проблема с этим классом заключается в том, что, в отличие от всего, что я делал, это не общий. Это означает, и исправьте меня, если я ошибаюсь здесь, что каждый раз, когда я получаю объект отсюда или перечисляю его, что происходит кастинг. Достаточно ли накладных расходов в более крупном объекте Dictionary<T>, чтобы оправдать накладные расходы не общего ListDictionary?Существует ли общая альтернатива классу ListDictionary?

Код, который будет использовать этот объект, будет перечислить на каждой загрузке страницы, что, я думаю, почему-то класс ListDictionary использовался по одной из других альтернатив. Именно поэтому я хотел бы получить максимальную производительность из этого списка данных.

+0

Вы пришли к выводу об этом и сделали какие-либо измерения производительности? Меня всегда беспокоит использование словаря ', когда в коллекции будет только несколько элементов, но удобство в этом всегда перевешивало беспокойство/риск, связанный с выбором или записью чего-то другого. Неважно, насколько это важно - если это не так. – Rory

ответ

10

К сожалению, не существует общего эквивалента ListDictionary.

Однако его не должно быть трудно реализовать. ListDictionary по существу работает, сохраняя связанный список пар «ключ/значение» и итерации по ним для операций поиска. Вы можете построить ListDictionary<TKey,TValue>, обернув LinkedList<T> с помощью очень простых выражений LINQ.

Например

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 будет отрицать почти все преимущества использования использования ListDictionary, если вычисление Hash Codes было ужасно дорого. – Chuu

+0

@Chuu Но ListDictionary уже вызывает Equals по каждому ключу при доступе к значениям, поэтому почему бы предоставить LINQ Где отрицательное влияние на производительность? – sluki

+1

@sluki Назначение объектов и делегирование делегатов по сравнению с одним методом, содержащим цикл for. LINQ предназначен для чтения, а не для кода фреймворка. – jnm2

4

Если данные, хранящиеся в ListDictionary, всегда являются объектами (классами), а не типами значений, то это, вероятно, будет быстрее, чем Словарь <T>. Если вы будете хранить типы значений (structs, int, double и т. Д.), Тогда стоимость бокса/unboxing, скорее всего, уравновесит ситуацию, и я бы порекомендовал вместо этого словарь <T>.

В целом, однако, я хотел бы указать, что разница в производительности между этими двумя, вероятно, будет наименее из ваших проблем с производительностью в целом. Маленькие вещи, подобные этому, как правило, являются последним, о чем нужно беспокоиться, когда речь заходит о оптимизации производительности. Более масштабные вещи, такие как межпроцессные вызовы, взаимодействие с базами данных и веб-сервисами и т. Д., Должны быть рассмотрены прежде, чем когда-либо быть обеспокоены незначительной разницей в производительности между ListDictionary и Dictionary <T>.

+0

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

1

Простая проверка на MSDN-ListDictionary класс покажет

Это простая реализация IDictionary с использованием односвязанны списка. Он меньше и быстрее, чем Hashtable, если количество элементов 10 или меньше. Этого нельзя использовать, если значение важно для больших номеров элементов.

1

Мы можем использовать,

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

Я думаю, что это поможет вам немного!

1

Нет никакого общего эквивалента ListDictionary.

Если использование этого маленького словаря не доминирует Add и Remove, вы могли бы рассмотреть SortedList<TKey, TValue>, которые, несмотря на свое название, реализует IDictionary<TKey, TValue>. В отличие от ListDictionary, который поддерживается односвязным списком, SortedList поддерживается массивом отсортированных ключей и значений массива.

+0

Я думаю, что это лучший ответ до сих пор. –

Смежные вопросы