6

我有可能是一个非常大的 Dictionary 对象列表,我需要从键中找到特定值。我当然可以做类似的事情

foreach(Dictionary<long, string> t in Foo)
{
    if (t.TryGetValue(key, out name))
        break;
}

这将愉快地遍历 Foo 直到找到密钥或 foreach 结束。

为了加快速度,我更喜欢使用少量的 LINQ。如果这是一个普通的列表,我会好的,但由于这是一个字典对象列表,我不太确定它是如何完成的。

帮助或建议表示赞赏。

4

4 回答 4

6

我认为你已经写了你想做的最有效的版本。由于 Linq 不能很好地处理输出参数,因此需要稍长一些的时间。但这里是你将如何做到这一点:

var dict = Foo.FirstOrDefault(d => d.ContainsKey(key));
if (dict != null) { dict.TryGetValue(key, out name); }
于 2013-05-07T17:47:40.423 回答
3

这段代码会更短,但会稍微长一点:

var dictWithKey = Foo.First(d => d.ContainsKey(key));
name = dictWithKey[key];

然而,真正的问题是为什么你要为此使用一个字典列表,特别是因为你说你想“加快速度”。这告诉我,您的代码可能会不止一次执行此操作,对吧?

更合适的方法可能是保留一个包含所有键/值对的字典,这样您就可以进行一次查找,而不是遍历多个字典。

于 2013-05-07T17:45:41.747 回答
0

好吧,根据字典的数量,Foo使用并行 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:89 毫秒
  • 原解:250ms

但是,我想强调的是,PLINQ 不一定总是让事情运行得更快的答案。在某些情况下,您的代码使用并行 foreach 循环来遍历少数元素,在后台启动线程的实际成本实际上比仅使用简单的 for 循环迭代要昂贵得多 - 所以,当有很多时使用它要迭代的元素:)

于 2013-05-07T17:56:46.007 回答
-1

您将密钥设置为长类型。

long key = 1;
Dictionary<long, string> name = foo.Where(d => d.ContainsKey(key)).First();
于 2013-05-07T17:50:01.980 回答