最近在进行在做一个链路选择的需求,涉及到字典存储。发现C#的Dictionary提供了ContainsKey和TryGetValue两个方法,都可以来判断字典中是否存在对应的Key值。那么这两个方法有什么区别呢?我们在编写代码的过程中如何选取呢?
我先创建了一个Dictionary<string, int>的字典,然后从0递增到一千万分别给这个字典添加了数据。
static Dictionary<string, int> dic = new Dictionary<string, int>();
const int TOTALNUM = 10000000;
for (int i = 0; i < TOTALNUM; i++)
{
dic.Add(i.ToString(), i);
}
我们借助StopWatch,对ContainsKey和TryGetValue分别进行一千万次的查找,比较两者所花费的时间。
Stopwatch stopwatch1 = new Stopwatch(); // TryGetValue
Stopwatch stopwatch2 = new Stopwatch(); // COntainsKey
测试环境:
当取出的Value在执行过程中有被使用时:
stopwatch1.Start();
long a = 0;
for (int i = 0; i < TOTALNUM; i++)
{
string str = i.ToString();
if (dic.TryGetValue(str, out var value))
{
// Value被使用
a = a + value;
}
}
stopwatch1.Stop();
stopwatch2.Start();
long b = 0;
for (int i = 0; i < TOTALNUM; i++)
{
string str = i.ToString();
if (dic.ContainsKey(str))
{
// Value被使用
b = b + dic[str];
}
}
stopwatch2.Stop();
ContainsKey所花费的时间较多
当没有对字典所对应Key的Value进行操作时:
...
if (dic.TryGetValue(str, out var value))
{
a = a + 1;
}
...
...
if (dic.ContainsKey(str))
{
b = b + 1;
}
...
TryGetValue花费的时间更多
查看源码:
public bool TryGetValue(TKey key, out TValue value)
{
int index = this.FindEntry(key);
if (index >= 0)
{
value = this.entries[index].value;
return true;
}
value = default(TValue);
return false;
}
public bool ContainsKey(TKey key)
{
return (this.FindEntry(key) >= 0);
}
public TValue this[TKey key]
{
get
{
int i = FindEntry(key);
if (i >= 0) return entries[i].value;
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
set
{
Insert(key, value, false);
}
}
查看源码我们发现TryGetValue是在ContainsKey的基础上直接从存储中取出Value。有一个很关键的函数FindEntry我们在三个函数都有看到,说明我们如果在使用完ContainsKey在用Dic[Key]去取值的时候,会多一次开销。
C# ContainsKey与TryGetValue方法探究
原文:https://www.cnblogs.com/fzuljz/p/14495697.html