想象一下代码:
public class obj
{
// elided
}
public static Dictionary<string, obj> dict = new Dictionary<string, obj>();
方法一
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,它实际上是相反的:
循环1000000个值(现有10万个和不存在90万个):
第一个功能:306毫秒
第二功能:20483毫秒
这是为什么?
编辑:正如您可以在此问题下方的注释中注意到的那样,在有0个不存在的键的情况下,第二个函数的性能实际上比第一个更好。但是,一旦至少有一个或多个不存在的密钥,第二个密钥的性能就会迅速下降。
@Petr
—
PatrykĆwiek2013年
O(1)
与字典中的查找相比,引发异常时涉及的指令要多得多……尤其是因为执行两个O(1)
操作仍是渐近的O(1)
。
正如下面的好答案中指出的那样,抛出异常的代价很高。他们的名字表明了这一点:它们是为例外情况保留的。如果您正在运行一个循环,在该循环中,您查询一百万次字典以查找不存在的键,那么这种情况就不再是一种特殊情况了。如果您要在字典中查询密钥,并且相对常见的情况是它们不存在密钥,那么首先检查是有意义的。
—
Jason R
不要忘记,您只比较了检查一百万个缺失值的成本和抛出一百万个异常的成本。但是,这两种方法在获取现有价值的成本上也有所不同。如果缺少密钥非常少见,则异常方法总体上将更快,尽管缺少密钥时代价更高。
—
Alexis
ContainsKey
预计O(1)
...