我有可能是一个非常大的Dictionary对象列表,我需要从键中找到一个特定的值。我当然可以做像
这样的事情foreach(Dictionary<long, string> t in Foo)
{
if (t.TryGetValue(key, out name))
break;
}
这将很高兴地遍历Foo,直到找到密钥或foreach结束。
为了加快速度,我宁愿使用少量的LINQ。如果这是一个普通的列表,我会没事的,但由于这是一个Dictionary对象列表,我不太清楚它是如何完成的。
帮助或建议表示赞赏。
答案 0 :(得分:6)
我认为你已经写了你想要做的最有效的版本。由于Linq不能很好地处理输出参数,因此需要稍长的时间。但是你会这样做:
var dict = Foo.FirstOrDefault(d => d.ContainsKey(key));
if (dict != null) { dict.TryGetValue(key, out name); }
答案 1 :(得分:3)
此代码会更短,但需要更长的时间:
var dictWithKey = Foo.First(d => d.ContainsKey(key));
name = dictWithKey[key];
但真正的问题是,为什么你要使用一个字典列表,特别是因为你说你想“加快速度”。这告诉我这可能是你的代码不止一次做的事,对吗?
更合适的方法可能是保留包含所有键/值对的单个字典,这样您就可以进行单个查找而不是遍历多个字典。
答案 2 :(得分:0)
那么,根据Foo
中词典的数量,使用Parallel LINQ(PLINQ)可能会有一个优势:
string name = null;
Parallel.ForEach(foo, f =>
{
if (name != null)
return;
if (f.ContainsKey(key))
name = f[key];
});
该实现假定给定键映射到相同的值或者该键在所有字典中是唯一的。此外,假设该值不为空。
5,000,000个词典包含一个键和一个值,比原始实现速度快150毫秒。
基准测试(2.4GHz Intel Core i5,带有两个物理内核和两个虚拟内核):
但是,我想强调的是,PLINQ并不一定总是让事情变得更快。在某些情况下,你有使用并行foreach循环遍历几个元素的代码,在后台启动线程的实际成本实际上要比使用简单的for循环迭代要昂贵得多 - 所以,当有很多时候使用它迭代的元素:)
答案 3 :(得分:-1)
您将密钥设置为长型。
long key = 1;
Dictionary<long, string> name = foo.Where(d => d.ContainsKey(key)).First();