为什么快检查字典包含的关键,而不是捕捉的情况下它不会例外? [英] Why is it faster to check if dictionary contains the key, rather than catch the exception in case it doesn't?

查看:238
本文介绍了为什么快检查字典包含的关键,而不是捕捉的情况下它不会例外?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下代码:

public class obj
{
    // elided
}

public static Dictionary<string, obj> dict = new Dictionary<string, obj>();



方法1

public static obj FromDict1(string name)
{
    if (dict.ContainsKey(name))
    {
        return dict[name];
    }
    return null;
}



方法2

public static obj FromDict2(string name)
{
    try
    {
        return dict[name];
    }
    catch (KeyNotFoundException)
    {
        return null;
    }
}



我很好奇,如果有在性能差异这两种功能,因为第一个应该会比第二个更慢 - 因为它需要检查两次,如果字典中包含一个值,而第二个功能确实需要查阅字典只有一次,但WOW,它实际上是相反的:

I was curious if there is a difference in performance of these 2 functions, because the first one SHOULD be SLOWER than second one - given that it needs to check twice if the dictionary contains a value, while second function does need to access the dictionary only once but WOW, it's actually opposite:

环路为1 000 000的值(100 000现有的和900 000不存在的):

Loop for 1 000 000 values (with 100 000 existing and 900 000 non existing):

第一个功能:306毫秒

first function: 306 milliseconds

第二个功能:20483毫秒

second function: 20483 milliseconds

?这是为什么

编辑:正如你可以在下面这个问题的意见通知,第二个函数的表现实际上是在情况稍微比第一个更好的有0个不存在的键。但是,一旦至少有1个或多个不存在的钥匙,迅速第二个下降的表现。

As you can notice in comments below this question, the performance of second function is actually slightly better than first one in case there are 0 non existing keys. But once there is at least 1 or more non existing keys, the performance of second one decrease rapidly.

推荐答案

在一方面,抛出异常本质上是昂贵的,因为堆栈已被退绕等。

在另一方面,它的关键一本字典访问值是便宜,因为它是一个快速,O(1)操作

On the one hand, throwing exceptions is inherently expensive, because the stack has to be unwound etc.
On the other hand, accessing a value in a dictionary by its key is cheap, because it's a fast, O(1) operation.

BTW:要做到这一点,正确的方法是使用 TryGetValue

BTW: The correct way to do this is to use TryGetValue

obj item;
if(!dict.TryGetValue(name, out item))
    return null;
return item;

这访问字典只有一次,而不是两次。结果
的如果你真的想刚刚返回如果该键不存在,上面的代码可以进一步简化:

This accesses the dictionary only once instead of twice.
If you really want to just return null if the key doesn't exist, the above code can be simplified further:

obj item;
dict.TryGetValue(name, out item);
return item;

这工作,因为 TryGetValue 项目如果与名称不存在任何键。

This works, because TryGetValue sets item to null if no key with name exists.

这篇关于为什么快检查字典包含的关键,而不是捕捉的情况下它不会例外?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆