C# Lookup() 和 Dictionary(Of list()) 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13362490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 08:18:54  来源:igfitidea点击:

Difference between Lookup() and Dictionary(Of list())

c#.netvb.netlinq

提问by John Bustos

I'm trying to wrap my head around which data structures are the most efficient and when / where to use which ones.

我正在努力思考哪些数据结构最有效以及何时/何地使用哪些数据结构。

Now, it could be that I simply just don't understand the structures well enough, but how is an ILookup(of key, ...)different from a Dictionary(of key, list(of ...))?

现在,可能是我只是不太了解这些结构,但是ILookup(of key, ...)a 与 a 有Dictionary(of key, list(of ...))什么不同?

Also where would I want to use an ILookupand where would it be more efficient in terms of program speed / memory / data accessing, etc?

另外,我想在ILookup哪里使用 an以及在程序速度/内存/数据访问等方面更有效的地方?

采纳答案by Jon Skeet

Two significant differences:

两个显着差异:

  • Lookupis immutable. Yay :) (At least, I believe the concrete Lookupclass is immutable, and the ILookupinterface doesn't provide any mutating members. There couldbe other mutable implementations, of course.)
  • When you lookup a key which isn't present in a lookup, you get an empty sequence back instead of a KeyNotFoundException. (Hence there's no TryGetValue, AFAICR.)
  • Lookup是不可变的。是的 :) (至少,我相信具体Lookup类是不可变的,并且ILookup接口不提供任何可变成员。当然,可能还有其他可变实现。)
  • 当您查找在查找中不存在的键时,您会返回一个空序列而不是KeyNotFoundException. (因此没有TryGetValue,AFAICR。)

They're likely to be equivalent in efficiency - the lookup may well use a Dictionary<TKey, GroupingImplementation<TValue>>behind the scenes, for example. Choose between them based on your requirements. Personally I find that the lookup is usually a better fit than a Dictionary<TKey, List<TValue>>, mostly due to the first two points above.

它们的效率可能相当——例如,查找很可能Dictionary<TKey, GroupingImplementation<TValue>>在幕后使用 a 。根据您的要求在它们之间进行选择。我个人发现查找通常比 a 更适合Dictionary<TKey, List<TValue>>,主要是由于上面的前两点。

Note that as an implementation detail, the concrete implementation of IGrouping<,>which is used for the values implements IList<TValue>, which means that it's efficient to use with Count(), ElementAt()etc.

注意,作为一个实现细节,的具体实现IGrouping<,>,其用于值工具IList<TValue>,这意味着它是有效的与使用Count()ElementAt()等等。

回答by James Michael Hare

Both a Dictionary<Key, List<Value>>and a Lookup<Key, Value>logically can hold data organized in a similar way and both are of the same order of efficiency. The main difference is a Lookupis immutable: it has no Add()methods and no public constructor (and as Jon mentioned you can query a non-existent key without an exception and have the key as part of the grouping).

aDictionary<Key, List<Value>>和 aLookup<Key, Value>逻辑上都可以保存以类似方式组织的数据,并且两者的效率顺序相同。主要区别是 aLookup是不可变的:它没有Add()方法和公共构造函数(正如 Jon 提到的,您可以毫无例外地查询不存在的键,并将键作为分组的一部分)。

As to which do you use, it really depends on how you want to use them. If you are maintaining a map of key to multiple values that is constantly being modified, then a Dictionary<Key, List<Value>>is probably better since it is mutable.

至于您使用哪个,这实际上取决于您想如何使用它们。如果您要维护一个映射到多个不断修改的值的键,那么 aDictionary<Key, List<Value>>可能更好,因为它是可变的。

If, however, you have a sequence of data and just want a read-only view of the data organized by key, then a lookup is very easy to construct and will give you a read-only snapshot.

但是,如果您有一系列数据并且只想要按键组织的数据的只读视图,那么查找非常容易构建,并且会为您提供只读快照。

回答by Servy

The primary difference between an ILookup<K,V>and a Dictionary<K, List<V>>is that a dictionary is mutable; you can add or remove keys, and also add or remove items from the list that is looked up. An ILookupis immutableand cannot be modified once created.

anILookup<K,V>和 a之间的主要区别在于Dictionary<K, List<V>>字典是可变的;您可以添加或删除键,还可以从查找的列表中添加或删除项目。AnILookup不可变的,一旦创建就无法修改。

The underlying implementation of both mechanisms will be either the same or similar, so their searching speed and memory footprint will be approximately the same.

两种机制的底层实现将相同或相似,因此它们的搜索速度和内存占用将大致相同。

回答by Mladen Mihajlovic

Interesting that nobody has stated the actual biggest difference (Taken directly from MSDN):

有趣的是,没有人说明实际最大的区别(直接取自MSDN):

A Lookup resembles a Dictionary. The difference is that a Dictionary maps keys to single values, whereas a Lookup maps keys to collections of values.

查找类似于字典。区别在于字典将键映射到单个值,而查找将键映射到值的集合。

回答by Noble_Bright_Life

Another difference not mentioned yet is that Lookup() supports null keys:

另一个尚未提及的区别是 Lookup()支持空键

Lookup class implements the ILookup interface. Lookup is very similar to a dictionary except multiple values are allowed to map to the same key, and null keys are supported.

Lookup 类实现了 Ilookup 接口。查找与字典非常相似,只是允许多个值映射到同一个键,并且支持空键。

回答by Fab

When exception is not a option, go for Lookup

当异常不是一个选项时,去查找

If you are trying to get a structure as efficient as a Dictionarybut you dont know for sure there is no duplicate key in input, Lookupis safer.

如果您试图获得与 a 一样有效的结构,Dictionary但您不确定输入中没有重复的键,Lookup则更安全。

As mentioned in another answer, it also supports null keys, and returns always a valid result when queried with arbitrary data, so it appears as more resilient to unknown input (less prone than Dictionary to raise exceptions).

正如另一个答案中提到的,它还支持空键,并且在使用任意数据查询时始终返回有效结果,因此它似乎对未知输入更具弹性(比字典更不容易引发异常)。

And it is especially true if you compare it to the System.Linq.Enumerable.ToDictionaryfunction :

如果将其与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);

The alternative would be to write your own duplicate key management code inside of a foreachloop.

另一种方法是在foreach循环内编写自己的重复密钥管理代码。

Performance considerations, Dictionary: a clear winner

性能考虑,字典:明显的赢家

If you don't need a list and you are going to manage a huge number of items, Dictionary(or even your own custom tailored structure) would be more efficient:

如果您不需要列表并且您要管理大量项目,Dictionary(甚至您自己定制的结构)会更有效:

        Stopwatch stopwatch = new Stopwatch();
        var list = new List<string>();
        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);
        // ...

As Lookuphas to maintain a list of items for each key, it is slower than Dictionary (around 3x slower for huge number of items)

由于Lookup必须为每个键维护一个项目列表,它比 Dictionary 慢(对于大量项目,大约慢 3 倍)

Lookup speed: Creation: 00:00:01.5760444

Dictionary speed: Creation: 00:00:00.4418833

查找速度:创建时间:00:00:01.5760444

字典速度:创建:00:00:00.4418833