哪种检查 NSDictionary 是不是包含特定键的方法更快?
Posted
技术标签:
【中文标题】哪种检查 NSDictionary 是不是包含特定键的方法更快?【英文标题】:Which method of checking to see if a NSDictionary contains a particular key is faster?哪种检查 NSDictionary 是否包含特定键的方法更快? 【发布时间】:2009-05-06 20:15:57 【问题描述】:我可以通过两种方式测试 NSDictionary 中是否存在键:
BOOL containsKey = [[dictionary allKeys] containsObject:foo];
BOOL containsKey = ([dictionary objectForKey:foo] != nil);
哪种方法更快,为什么?
【问题讨论】:
"请展示你的作品?"您拥有与我们相同的工具。如果您想知道此类问题的答案,您应该尝试分析不同的代码。 Daniel 是绝对正确的,这是一种非常懒惰的方式来获得易于测试的问题的答案。但是我得到了一些非常好的答案和一些真实的性能结果,所以谢谢大家让我有点懒。 我知道人们对上面问题中的“请展示你的作品”这一行有点失望,但我认为堆栈溢出的目的是为了回答各种基本问题, 不?所以,澄清一下,我没有问这个,因为我不知道答案,找不到自己,或者是一个粗鲁的混蛋。相反,因为除非您熟悉 Foundation 系列,否则答案不会立即显而易见,这似乎是一个很好的问题和答案。 这个问题已经引起了我们社区的多个标志。我对您的问题进行了小幅编辑,请考虑保留它(或将我的编辑修改为任何内容,而不是原来的内容)。 我完全没有意识到我可以在事后编辑问题。 /掌脸 【参考方案1】:哈希查找通常比遍历所有字典键、从它们创建一个数组(内存分配相对昂贵)然后搜索数组(甚至不能是二进制搜索,因为数组是未排序)。
不过,为了科学起见,我制作了两个可执行文件,每个样式只执行 100 万次并对其进行计时。
使用所有键:
real 0m4.185s
user 0m3.890s
sys 0m0.252s
使用 objectForKey:
real 0m0.396s
user 0m0.189s
sys 0m0.029s
显然,各种因素都会影响这一点——字典的大小、缓存 allKeys 返回值等。不过,我不希望出现数组搜索比字典查找更快的情况。
【讨论】:
Chuck,你能用字典中的字典来测试 valueForKey 吗?我认为除了知道 objectForKey 执行得更快之外,这将是最有用的。提前致谢。【参考方案2】:我看不出请求 allKeys 数组如何可能更快,否则 NSDictionary 至少会在内部执行等效操作。
编辑:我想你可以构建一个 allKeys
方法会更快的情况 - 例如,通过在你的密钥的 hash
方法中花费很长时间,而不是在你的 isEqual:
方法中。你也可以为NSDictionary
交换一个疯狂的实现,它们也被交换(因为NSDictionary
是抽象的。)
【讨论】:
同意。要求 allKeys 会给你一个 NSArray,其中 containsObject 必须迭代地搜索寻找 foo。另一方面,objectForKey 将使用哈希来计算 foo 在字典中的位置,以便可以直接确定 foo 的存在。【参考方案3】:在考虑此类性能问题时,请记住,Foundation 数据类会根据您在其中存储的对象数量来交换其底层数据结构。例如,我认为一个小的 NSArray 实际上使用哈希表进行存储,直到它达到一定的大小。
【讨论】:
哈希表不是更有可能变得更有益吗?测试 10 个左右的对象是否相等是微不足道的。虽然有几千个对象,但哈希表是一个明显的胜利。 你很可能是对的,我记得前段时间有人写了一篇关于这个的文章(连同基准测试),但从那以后我没有考虑太多。 ridiculousfish.com/blog/posts/array.html 将是您正在考虑的帖子以上是关于哪种检查 NSDictionary 是不是包含特定键的方法更快?的主要内容,如果未能解决你的问题,请参考以下文章