2013-12-26 3 views
2

Предположим, что у нас есть 2 варианта: пойтисловарь размер явной инициализации: плюсы и минусы

public static Dictionary<TK, TV> GetDictionary(IEnumerable<TK> keys) 
    { 
     var result = new Dictionary<TK, TV>(); 
     ... 
     return result; 
    } 

против

public static Dictionary<TK, TV> GetDictionary(IEnumerable<TK> keys) 
    { 
     var result = new Dictionary<TK, TV>(keys.Count()); 
     ... 
     return result; 
    } 

Каковы плюсы и минусы каждого из них? Недавно в нашей команде у нас был спор.

Возможные минусы явного размера

  1. Если количество элементов мало, то это не имеет никакого смысла.
  2. Если количество элементов велико, тогда Count() стоит дорого и ведет к полному перечислению IEnumerable.
  3. Изменение размера словаря является эффективным и быстрым - нет необходимости его оптимизировать.

Возможные плюсы явного размера

  1. Precise получает номер производительности потому словарь изменение размеров дорого и лучше избегать.

Какой вариант лучше или есть какое-нибудь эмпирическое правило?

+1

Любые доказательства, на самом деле имеющие какое-либо значение в вашем случае? Я был бы очень удивлен. – Baldrick

+0

@ Baldrick Я спрашиваю об общем случае, поэтому ваш вопрос - это то же самое, и мне все равно, не так ли? –

+0

Общее правило - сначала использовать простейшую форму, которая почти наверняка будет прекрасной. Если в словаре есть проблемы с производительностью, только тогда вы должны рассмотреть возможность микрооптимизации на этом уровне. Кстати, в случае, когда вы упоминаете, вы можете конвертировать IEnumerable в словарь с использованием linq. – Baldrick

ответ

2

Если вы работаете с большим количеством предметов и, вы знаете это число в O (1) раз, я бы подумал о предоставлении Dictionary с этой информацией. Как правило, если дешево прекоммутировать что-то, то может сделать разницу в определенных сценариях.

Итак, в вашем случае, если вы действительно работаете с большим количеством элементов и сможете подсчитать количество, не перечислив их все (что и делает метод расширения Count()), а затем вперед. На практике это означает, что вы должны передать по крайней мереICollection<T> в ваш метод:

public static Dictionary<TK, TV> GetDictionary(ICollection<TK> keys) 
{ 
    var result = new Dictionary<TK, TV>(keys.Count); 
    ... 
    return result; 
} 

Если вы не знать количество в O (1) время каждый раз вам нужно построить что dictionray, затем just don't spend time optimizing something that's not causing a performance problem.

+0

Интересно, какие именно случаи, когда граф предварительно вычисляется и становится дешевым? Предположим, у меня есть запрос против списка ... И, рассматривая возможность изменения типов с 'IEnumerable' на' ICollection' - он делает вопрос бессмысленным, как только основной смысл - это более дорогостоящее перечисление или изменение словаря (и в каких случаях)? –

+0

Как правило, 'IEnumerable ' может предоставить потенциально бесконечное количество элементов (однако это угловой регистр, и обычно это не так). 'ICollection ' явно заявляет, что в нем имеется известное количество элементов. Каждый здравомыслящий автор класса коллекции поддерживает текущее количество элементов, хранящихся в нем, потому что просить об этом является очень распространенным случаем. Изменение с 'IEnumerable ' '' ICollection 'не отменяет ваш вопрос. Это просто вопрос эффективности и выраженное ожидание качеств ввода. –

+0

У меня есть ограниченное знание фактического типа, которое можно получить после применения оператора 'Where' к коллекции, но я сомневаюсь, что у него есть свойство Count. Думаю, это отличает ситуацию. –

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