【问题标题】:Which method to pick for the Dictionary element look-up by key?选择哪种方法来按键查找 Dictionary 元素?
【发布时间】:2013-04-11 20:22:30
【问题描述】:

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

//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"
    }
}

【问题讨论】:

  • Marcin 为您的问题提供了很好的解决方案。我只是想说明一下,使用 try/catch 进行决策总是一个坏主意,因为它要慢得多。仅使用 try/catch 捕获意外异常。
  • @Quintium:是使用try/catch 块使其变慢,还是只有在抛出异常时才会变慢?
  • @ahmd0 仅在实际抛出异常时。
  • @MarcinJuraszek:再次感谢。只是出于好奇,如果抛出异常,我们在谈论多少“浪费”?
  • @ahmd0 - 是的,很抱歉通过它总是很慢。不,正如 Marcin 所说,只有在被抛出时。但是作为一个例子,如果你知道有机会,最好再次检查 NULL,而不是捕获 NullException

标签: c# .net dictionary


【解决方案1】:

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

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

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

应该声明为int?,而不是允许null值:

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

    return null;
}

我认为这将是最好的。但是,如果我必须从您建议的两种方法中进行选择,我会选择第一种 - 第二种看起来更快,但是当抛出异常时,它不会那么快,因为它必须被处理,并且需要一些工作量.

【讨论】:

  • 哦,非常好。我没有意识到这种方法存在。非常感激。 (PS。我在原来的帖子中没有意识到int 不能是null...哎呀。)
【解决方案2】:

您可以使用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

如你所见,抛出异常时抛出exceptionskillsperformance

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

【讨论】:

    【解决方案3】:

    没有。最好搭配:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-17
      • 2018-08-21
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 2010-10-16
      相关资源
      最近更新 更多