Разница между Lookup () и словарем (из списка ())

Я пытаюсь обернуть голову вокруг того, какие структуры данных являются наиболее эффективными и когда / где их использовать.

Теперь может быть, что я просто недостаточно хорошо разбираюсь в структурах, но как ILookup(of key, ...) отличается от Dictionary(of key, list(of ...)) ?

Также где я хочу использовать ILookup и где он будет более эффективным с точки зрения скорости программы / памяти / доступа к данным и т. Д.?

Две существенные отличия:

  • Lookup неизменен. Yay 🙂 (По крайней мере, я считаю, что конкретный class Lookup неизменен, и интерфейс ILookup не предоставляет каких-либо мутирующих элементов. Конечно, могут быть и другие изменчивые реализации).
  • Когда вы просматриваете ключ, отсутствующий в поиске, вы получаете пустую последовательность вместо KeyNotFoundException . (Следовательно, нет TryGetValue , AFAICR.)

Они, вероятно, будут эквивалентны по эффективности – поиск может, например, использовать Dictionary> за кулисами. Выбирайте между ними, исходя из ваших требований. Лично я считаю, что поиск обычно лучше, чем Dictionary> , в основном из-за первых двух пунктов выше.

Обратите внимание, что в качестве детали реализации конкретная реализация IGrouping<,> которая используется для значений, реализует IList , что означает, что она эффективна для использования с Count() , ElementAt() и т. Д.

Интересно, что никто не заявил о самой большой разнице (взятой непосредственно из MSDN ):

Поиск похож на словарь. Разница заключается в том, что словарь сопоставляет ключи с одиночными значениями, тогда как Lookup сопоставляет ключи с наборами значений.

Dictionary> и Lookup логически могут хранить данные, организованные аналогичным образом, и оба имеют один и тот же порядок эффективности. Основное различие заключается в том, что Lookup неизменен: у него нет методов Add() и нет конструктора public (и, как сказал Jon, вы можете запросить несуществующий ключ без исключения и иметь ключ как часть группировки).

Что касается того, что вы используете, это действительно зависит от того, как вы хотите их использовать. Если вы поддерживаете карту ключа для нескольких значений, которые постоянно изменяются, то Dictionary> , вероятно, лучше, поскольку он изменен.

Если, однако, у вас есть последовательность данных и вы просто хотите просмотреть только данные, организованные ключом, то поиск очень прост в построении и даст вам мгновенный снимок только для чтения.

Основное различие между ILookup и Dictionary> заключается в том, что словарь изменен; вы можете добавлять или удалять ключи, а также добавлять или удалять элементы из списка, который просматривается. ILookup является неизменным и не может быть изменен после создания.

Основная реализация обоих механизмов будет либо одинаковой, либо подобной, поэтому их скорость поиска и объем памяти будут примерно одинаковыми.

Еще одно отличие еще не упомянуто, что Lookup () поддерживает нулевые ключи :

Класс Lookup реализует интерфейс ILookup. Lookup очень похож на словарь, за исключением того, что нескольким значениям разрешено сопоставлять один и тот же ключ, а нулевые ключи поддерживаются.

Когда исключение не является вариантом, перейдите к Lookup

Если вы пытаетесь получить такую ​​же эффективную структуру, как и Dictionary но вы точно не знаете, что на вводе нет дублирующего ключа, Lookup безопаснее.

Как упоминалось в другом ответе, он также поддерживает нулевые ключи и всегда возвращает действительный результат при запросе с произвольными данными, поэтому он кажется более устойчивым к неизвестному входу (менее подвержен, чем словарь, который вызывает исключения).

И это особенно верно, если вы сравните его с функцией System.Linq.Enumerable.ToDictionary :

 // won't throw new[] { 1, 1 }.ToLookup(x => x); // System.ArgumentException: An item with the same key has already been added. new[] { 1, 1 }.ToDictionary(x => x); 

Альтернативой было бы написать собственный код управления ключевыми ключами внутри цикла foreach .

Соображения производительности, словарь: явный победитель

Если вам не нужен список, и вы собираетесь управлять огромным количеством предметов, Dictionary (или даже ваша собственная индивидуальная структура) будет более эффективным:

  Stopwatch stopwatch = new Stopwatch(); var list = new List(); for (int i = 0; i < 5000000; ++i) { list.Add(i.ToString()); } stopwatch.Start(); var lookup = list.ToLookup(x => x); stopwatch.Stop(); Console.WriteLine("Creation: " + stopwatch.Elapsed); // ... Same but for ToDictionary var lookup = list.ToDictionary(x => x); // ... 

Поскольку Lookup должен поддерживать список элементов для каждого ключа, он медленнее, чем Dictionary (примерно на 3 раза медленнее для огромного количества элементов)

Скорость поиска: Создание: 00: 00: 01.5760444

Скорость словаря: Создание: 00: 00: 00.4418833

  • Может ли PictureBox показывать анимированный GIF в приложении Windows?
  • Веб-страница работает в IE, Chrome и Firefox, но не при использовании элемента управления .NET WebBrowser
  • Как подсчитать количество строк в excel с данными?
  • Создание нового пользовательского интерфейса TaskFactory
  • Использование оператора и IDisposable.Dispose ()
  • Графическая библиотека .NET вокруг?
  • .NET Core не знает о Windows 1252, как исправить?
  • Получение hashа списка строк независимо от порядка
  • Опция Strict по умолчанию в VB.NET
  • Зачем использовать String.Format?
  • Как поместить данные, содержащие двойные кавычки в строковой переменной?
  • Давайте будем гением компьютера.