Pet*_*etr 234 c# performance dictionary
想象一下代码:
public class obj
{
// elided
}
public static Dictionary<string, obj> dict = new Dictionary<string, obj>();
Run Code Online (Sandbox Code Playgroud)
方法1
public static obj FromDict1(string name)
{
if (dict.ContainsKey(name))
{
return dict[name];
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
方法2
public static obj FromDict2(string name)
{
try
{
return dict[name];
}
catch (KeyNotFoundException)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我很好奇这两个函数的性能是否存在差异,因为第一个函数应该比第二个函数更低 - 假设它需要在字典包含值时检查两次,而第二个函数确实只需要访问字典曾经但是WOW,它实际上是相反的:
循环1 000 000个值(现有10万个,不存在90 000个):
第一个功能:306毫秒
第二功能:20483毫秒
这是为什么?
编辑:你可以在下面这个问题的评论中注意到,如果有0个非现有密钥,第二个函数的性能实际上略好于第一个函数.但是,一旦存在至少一个或多个非现有密钥,则第二个密钥的性能会迅速下降.
Dan*_*rth 402
一方面,抛出异常本质上是昂贵的,因为堆栈必须被展开等.
另一方面,通过其密钥访问字典中的值是便宜的,因为它是一个快速的O(1)操作.
顺便说一句:正确的方法是使用 TryGetValue
obj item;
if(!dict.TryGetValue(name, out item))
return null;
return item;
Run Code Online (Sandbox Code Playgroud)
这只访问字典一次而不是两次.
如果您确实想要null
在密钥不存在时返回,则可以进一步简化上述代码:
obj item;
dict.TryGetValue(name, out item);
return item;
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为如果没有key 存在则TryGetValue
设置item
为.null
name
小智 6
字典专门用于执行超快速键查找.它们作为哈希表实现,条目越多,它们相对于其他方法就越快.使用异常引擎只应该在您的方法无法完成您设计的操作时完成,因为它是一组很大的对象,为您提供了许多处理错误的功能.我构建了一个完整的库类,其中包含try catch块所包围的所有内容,并且看到调试输出包含600多个异常中的每一个的单独行!
归档时间: |
|
查看次数: |
125367 次 |
最近记录: |