检索字典价值最佳实践


79

我最近才注意到,Dictionary.TryGetValue(TKey key, out TValue value)并且很好奇哪种方法是从“字典”中检索值的更好方法。

传统上我做过:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...

除非我知道它必要在里面。

这样做是否更好:

if (myDict.TryGetValue(somekey, out someVal)
    ...

哪个更好的做法?一个比另一个快吗?我想像一下,Try版本会变慢,因为它会“吞并”内部的try / catch并将其用作逻辑,不是吗?

Answers:


84

TryGetValue稍快一些,因为FindEntry仅被调用一次。

快多少?这取决于手头的数据集。当您调用Contains方法时,Dictionary会进行内部搜索以找到其索引。如果返回true,则需要另一个索引搜索以获取实际值。当您使用TryGetValue时,它仅搜索一次索引,如果找到,它将为您的变量分配值。

仅供参考:实际上并没有发现错误。

它在打电话:

public bool TryGetValue(TKey key, out TValue value)
{
    int index = this.FindEntry(key);
    if (index >= 0)
    {
        value = this.entries[index].value;
        return true;
    }
    value = default(TValue);
    return false;
}

ContainsKey是这样的:

public bool ContainsKey(TKey key)
{
    return (this.FindEntry(key) >= 0);
}

TryGetValue稍快一些,因为FindEntry仅被调用一次。

1
使用大型词典时,TryGetValue的速度要快得多
Diadistis

4
从理论上讲(当然也是在实践中),这不应该依赖于字典的大小,因为预期的检索时间是恒定的,即与字典的大小无关!
康拉德·鲁道夫

29

实际上,TryGetValue更快。快多少?这取决于手头的数据集。当您调用Contains方法时,Dictionary会进行内部搜索以找到其索引。如果返回true,则需要另一个索引搜索以获取实际值。当您使用TryGetValue时,它仅搜索一次索引,如果找到,它将为您的变量分配值。

编辑:

好的,我了解您的困惑,所以让我详细说明一下:

情况1:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];

在这种情况下,有2次对FindEntry的调用,一次是检查密钥是否存在,一次是对其进行检索。

情况2:

myDict.TryGetValue(somekey, out someVal)

在这种情况下,只有一次对FindKey的调用,因为在同一方法中保留了用于实际检索的结果索引。


同意 TryGetValue消除了两次进行密钥查找的需要。在多线程的情况下它也可以提供帮助。在您检查该值是否存在之间,可能已添加或删除了该值。这可能导致“密钥已存在”或“找不到密钥”异常。
布赖恩·鲁道夫

0

我认为trygetvalue的作用类似于:

if(myDict.ReallyOptimisedVersionofContains(someKey))
{ 
  someVal = myDict[someKey];
  return true;
}
return false;

因此希望在任何地方都不会尝试/捕获。

我认为这实际上只是一种方便的方法。我通常使用它,因为它可以节省一行或两行代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.