【发布时间】:2015-10-30 10:27:12
【问题描述】:
当从字典中获取一个你不确定是否存在的键时,你通常会使用TryGetValue 而不是ContainsKey + get indexer 以避免检查键两次的开销。换句话说,这是:
string password;
if (accounts.TryGetValue(username, out password))
{
// use the password
}
会更喜欢这个:
if (accounts.ContainsKey(username))
{
string password = accounts[username];
}
如果我想在将某个键设置为某个值之前检查它是否已经存在,该怎么办?例如,我想在用新密码覆盖之前检查用户名是否存在:
if (!accounts.ContainsKey(username))
{
accounts.Add(username, password);
}
else
{
Console.WriteLine("Username is taken!");
}
对
// this doesn't exist
if (!accounts.TrySetValue(username, password))
{
Console.WriteLine("Username is taken!");
}
有没有比ContainsKey 和Add 更性能 的替代方案?
【问题讨论】:
-
var password = keyValue.Where(entry => entry.Key.Contains("password")) .Select(item => item.Key).FirstOrDefault();
-
@SanjeevS 感谢您的回答,但 LINQ 甚至比我上面发布的后备解决方案效率低得多。
-
我不确定这里有什么收获,因为字典在内部基于哈希表,因此通过键获取值(例如使用索引器)具有 O(1) 复杂性.
-
@JamesKo:你在追逐阴影。
TryGetValue调用私有函数FindEntry。ContainsKey也调用相同的私有FindEntry函数。索引器还调用FindEntry。据我所知,FindEntry看起来非常快。你有没有分析过你的代码?你想解决什么问题? -
@JamesKo 这就是为什么你事先打电话给
ContainsKey。密钥集合是散列的,查找的复杂度为 O(1)。最坏情况的复杂度是 O(n),但只有当你有很多哈希冲突时才会出现这种情况(这就是为什么仔细覆盖GetHashCode很重要)。我将加入其他人并建议您分析您的代码。除非你试图做“理论优化”,在这种情况下没有明确的答案。
标签: c# performance dictionary data-structures hashtable