通过键选择Dictionary元素查找的方法是什么?

时间:2013-04-11 20:22:30

标签: c# .net dictionary

我想知道,速度方面,以下哪种方法更为可取?

//Dictionary dic<string, int>;

int getElementByKey1(string key)
{
    if(dic.ContainsKey(key))     //Look-up 1
        return dic[key];     //Look-up 2 in case of a "hit"

    return null;
}

int getElementByKey2(string key)
{
    try
    {
        return dic[key];      //Single look-up in case of a "hit"
    }
    catch
    {
        return null;          //Exception in case of a "miss"
    }
}

3 个答案:

答案 0 :(得分:6)

第三个怎么样,使用TryGetValue()方法:

int getElementByKey3(string key)
{
    int value;
    dic.TryGetValue(key, out value)
    return value;
}

顺便说一句:您的方法无效,因为您无法从声明为null的方法返回int

应将其声明为int?,以允许null值:

int? getElementByKey3(string key)
{
    int value;
    if(dic.TryGetValue(key, out value))
        return value;

    return null;
}

我认为这将是最好的一个。但是如果我不得不从你那里选择两个建议的方法我会选择第一个 - 第二个看起来更快,但是当抛出Exception时它不会那么快,因为它必须被处理,它需要一些工作量

答案 1 :(得分:1)

您可以使用StopWatchers测试执行时间,首先,在Dictionary上添加一些值:

    Random r = new Random();
    for (int i = 0; i < 10000; i++)
    {
        d.Add(Guid.NewGuid().ToString(), r.Next());

        //put some manual key for search later
        if (i == 9001)
            d.Add("it's over", 9000);
    }

然后,使用StopWatchers(使用System.Diagnostics)进行一些搜索:

  • 首次测试,当值存在时(不抛出异常):

    Stopwatch st1 = new Stopwatch();
    st1.Start();
    int getKey1 = getElementByKey1("it's over");
    st1.Stop();
    
    Stopwatch st2 = new Stopwatch();
    st2.Start();
    int getKey2 = getElementByKey2("it's over");
    st2.Stop();
    

我的电脑结果:

Time spent on first search: 00:00:00.0002738
Time spent on second search: 00:00:00.0001169

因此,第一个更慢,因为在返回值之前验证if (d.ContainsKey(key))

  • 第二次测试,当值不存在时(抛出异常,例如:int getKey1 = getElementByKey1("nevermind");):

结果:

Time spent on first search: 00:00:00.0002331
Time spent on second search: 00:00:00.0822669

如您所见,抛出异常时抛出exceptions kills performance

注意:您不能在返回int的方法上返回null,因此我使用了return 0;

答案 2 :(得分:0)

无。最好配合:

string result = null;
if (dic.TryGetValue(key, out result)
{
    // don't know, maybe log it somewhere or sth?
}

return result;