读取nsdictionary与nsarray的性能

时间:2012-05-10 23:37:44

标签: objective-c c xcode performance benchmarking

继续发表这篇文章:Performance hit incurred using NSMutableDictionary vs. NSMutableArray>

我正在尝试进行一些测试,以确定性能差距是否非常适合NSArray和EXA之间的读写操作。 NSDictionary以及他们可变的coutnerparts ......

然而,我很难找到一个“平衡”测试...因为字典有2个(或3个,具体取决于你如何看待这个)对象循环以获取所寻找的值(而不是键),而数组只有一个...

有什么建议吗?

- 如果您想了解更多详情: 我的意思是通过例子更容易解释;

对于数组: (对于NSString * str in array){do smth with the string}

字典

(for NSString *str in [dictionary allValues]) { string }

OR

(for NSString *str in [dictionary allKeys]) { [dictionary valueForKey:key] }

OR

(for NSString *str in [dictionary allKeys]) { string }

或偶然

NSArray *valuesOrKeys = [dictionary allKeys/allValues];

(for NSString *str in valuesOrKeys) {string }

为字典做什么是“最公平”的测试?

- 编辑(评论)

正如大家所指出的那样(并问我为什么会这么想),当使用字典时,这是因为它比数组更适合模型......

我问的原因是我正在构建的应用程序非常缓慢,所以我试图弄清楚是否使用不同的数据类型会改变其中任何一个,我正在考虑使用基本的c数组......我现在有了选择,所以我能够改变内部工作方式以适应我想要的任何类型......

3 个答案:

答案 0 :(得分:11)

我想指出以下文章:“Array”,来自Apple的工程师ridiculous_fish。 Cocoa数组不一定是你想象中的天真数组,也不是字典简单的哈希表。它们的表现非常具有间接性,取决于它们所拥有的物体数量(以及它们的价值等)。这可能不会直接影响答案,但需要考虑(NSDictionary性能当然会随着散列函数的速度和可靠性而变化,等等。)

此外,如果您正在寻找“平衡”测试,您必须寻找一种方法让两个类尽可能彼此接近。您希望排除通过字典中的键访问值,因为 - 无论NSDictionary维护的基础数据结构的搜索时间有多快 - 都比单纯从数组中提取对象要慢,因为您正在执行做更多的操作。对于哈希表,数组访问为O(1),最好为O(1),最差为O(n)(具体取决于实现,位于中间某处)。

如上所述,有几种方法可以枚举字典和数组。您将要在实现方面使用彼此最接近的方法,这些方法是基于块的枚举(enumerateObjectsUsingBlock: NSArrayenumerateKeysAndObjects: NSDictionary }}或快速枚举(对allKeys使用allValuesNSDictionary)。因为这些算法的性能主要是经验性的,所以我进行了几次测试来记录访问时间(每个都有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的最快枚举只是简单地将其转换为数组。

所以最大的问题是,你为什么要考虑使用字典?数组和哈希表不完全可以互换;你有什么样的模型允许用NSArray直接替换NSDictionary?无论人工举例说明如何以某种方式证明性能优势,您都应该始终以能够理解的方式实现模型 - 如果必须,您可以稍后优化性能。我不知道你将如何交替使用这些数据结构,但无论如何,NSArray在这里是赢家,特别是考虑到你试图访问值的顺序。

答案 1 :(得分:5)

这是使用快速枚举的“平衡”测试:

[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    // do something with objects    
}];
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    // do something with objects    
}];

答案 2 :(得分:1)

  

我正在尝试进行一些测试,看看是否存在性能差距   非常适合NSArray和&amp ;;之间的读写。 NSDictionary以及   他们可变的coutnerparts ...

为什么呢?如果它只是为了满足你的好奇心,这是一回事。但通常如果你需要一个字典,一个数组真的不会这样做,反之亦然。因此,在给定的操作中哪一个更快是无关紧要的 - 它不是一个对另一个更好的选择。

  

然而,我很难找到一个“平衡”的测试......因为   字典有2个(或3个,具体取决于你如何看待这个)对象   循环通过获取值(而不是键)寻找,而数组   只有一个...

你在这里做了一些不太可能有效的假设。访问任何一种容器的元素都可能没有太多的循环。