继续这篇文章:使用 NSMutableDictionary 与 NSMutableArray 对性能造成影响>
我正在尝试运行一个小测试,看看 NSArray 和 NSDictionary 以及它们的可变部分之间的读写性能差距是否那么大......
但是,我很难找到"平衡"的测试......因为字典有 2 个(或 3 个,取决于您如何看到这个(对象要循环以获取所寻求的值(而不是键(,而数组只有一个......
有什么建议吗?
--如果您想了解更多详情:我的意思更容易通过例子来解释;
对于数组:(对于阵列中的 NSString *str({ 用字符串做 smth }
对于字典
(for NSString *str in [dictionary allValues]) { string }
或
(for NSString *str in [dictionary allKeys]) { [dictionary valueForKey:key] }
或
(for NSString *str in [dictionary allKeys]) { string }
甚至
NSArray *valuesOrKeys = [dictionary allKeys/allValues];
(for NSString *str in valuesOrKeys) {string }
对字典进行的"最公平"测试是什么?
--编辑(评论(
正如你们都指出的那样(并问我为什么想要那个(,当使用字典时,是因为它比数组更适合模型......
好吧,我问的原因是我正在构建的应用程序非常慢,所以我试图弄清楚使用不同的数据类型是否会改变其中的任何一种,我正在考虑使用基本的 c 数组......在这一点上我可以选择,所以我能够改变内部工作原理以适应我想要的任何类型......
给你指出以下文章:"Array",由苹果公司的工程师ridiculous_fish。Cocoa 数组不一定像您期望的那样是实现良好的朴素数组,字典也不是简单的哈希表。它们的性能是非常偶然的,并且取决于它们所持有的对象的数量(以及它们的值等(。这可能不会直接影响答案,但需要考虑(当然,NSDictionary
性能会随着哈希函数的速度和可靠性而变化,等等(。
此外,如果您正在寻找"平衡"测试,则必须寻找一种让两个类的行为尽可能接近彼此的方法。您希望排除通过字典中的键访问值,因为无论 NSDictionary
维护的基础数据结构的寻道时间有多快,都比简单地从数组中提取对象慢,因为您要执行更多操作来执行此操作。从数组访问是O(1)
的,对于哈希表,充其量是O(1)
,最坏O(n)
(取决于实现,在中间的某个地方(。
如上所述,有几种方法可以枚举字典和数组。您将需要使用在实现方面彼此最接近的方法,这些方法要么是基于块的枚举(enumerateObjectsUsingBlock:
用于NSArray
,enumerateKeysAndObjects:
用于NSDictionary
(,要么是快速枚举(对NSDictionary
使用allKeys
或allValues
(。由于这些算法的性能主要是经验性的,因此我执行了几次测试来记录访问时间(每个测试有 10000 个NSNumber
对象(:
NSArray, Block Enumeration:
1. 10.5s
2. 9.1s
3. 10.0s
4. 9.8s
5. 9.9s
-----
9.9s Avg
NSArray, Fast Enumeration:
1. 9.7s
2. 9.5s
3. 9.3s
4. 9.1s
5. 10.5s
-----
9.6s Avg
NSDictionary, Block Enumeration
1. 10.5s
2. 10.6s
3. 9.9s
4. 11.1s
5. 11.0s
-----
10.6s Avg
NSDictionary, allKeys -> Fast Enumeration
1. 10.0s
2. 11.2s
3. 10.2s
4. 10.8s
5. 10.8s
-----
10.6s Avg
NSDictionary, allValues -> Fast Enumeration
1. 10.7s
2. 10.3s
3. 10.5s
4. 10.5s
5. 9.7s
-----
10.3s Avg
从这个人为测试的结果中可以看出,NSDictionary
显然比NSArray
慢(使用块枚举慢约 7%,使用快速枚举慢 7-10%(。但是,这种比较毫无意义,因为无论如何,使用最快的NSDictionary
枚举只是将其下放到数组中。
所以最大的问题是,你为什么要考虑使用字典?数组和哈希表不能完全互换;您有什么样的模型可以直接用NSDictionary
替换NSArray
?无论人为示例给出多少时间来证明性能优势,您都应该始终以有意义的方式实现模型 - 如有必要,您可以在以后针对性能进行优化。我不明白您将如何互换使用这些数据结构,但无论如何,NSArray
是这里的赢家,特别是考虑到您尝试访问值的顺序。
以下是使用快速枚举的"平衡"测试:
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
// do something with objects
}];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
// do something with objects
}];
我正在尝试运行一些测试以查看性能差距是否为 非常适合在NSArray和NSDictionary之间读写,以及 他们可变的库特纳部分...
为什么?如果只是为了满足你的好奇心,那是一回事。但通常如果你需要一个字典,数组真的不行,反之亦然。因此,在给定的操作中,哪一个更快并不重要 - 这并不是说一个是另一个的好选择。
但是,我很难找到"平衡"的测试......因为 字典有 2 个(或 3 个,取决于您如何看到这一点(对象到 循环获取所查找的值(而不是键(,而数组 只有一个...
你在这里做了一些不太可能有效的假设。访问这两种容器的元素可能不涉及很多循环。