【发布时间】:2012-06-15 09:06:08
【问题描述】:
【问题讨论】:
标签: ios objective-c arrays cocoa cocoa-touch
【问题讨论】:
标签: ios objective-c arrays cocoa cocoa-touch
当集合中项目的顺序不重要时,集合为查找集合中的项目提供了更好的性能。
原因是集合使用哈希值来查找项目(如字典),而数组必须遍历其全部内容才能找到特定对象。
【讨论】:
Apple's Documentation的图片描述的很好:
Array 是一个有序(添加时保持顺序)元素序列
[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];
[1, 2, 3, 4, 6, 4, 1, 2]
Set 是一个不同(无重复)、无序元素列表
[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];
[1, 2, 6, 4, 3]
【讨论】:
最好的答案是Apple's own documentation。
主要区别在于NSArray 用于有序集合,NSSet 用于无序集合。
有几篇文章讨论了两者之间的速度差异,例如this one。如果您正在遍历无序集合,NSSet 非常棒。但是,在许多情况下,您需要做只有 NSArray 才能做的事情,因此您牺牲了这些能力的速度。
NSSet
NSArray
这就是它的全部内容!让我知道这是否有帮助。
【讨论】:
NSSet。对相同的数据使用两种不同的数据结构是很常见的。或者您在该数组上构建和索引 :) 但是最好使用已经实现的数据库。
NSSet和NSArray,所以我的回答是准确而完整的。是的,您可以构建其他数据结构,但我只是比较这两个。
NSArray 的一些功能和NSSet 的一些功能,正确的答案不是“使用NSArray 并牺牲性能”。答案是结合两者或使用不同的数据结构。
数组用于通过索引访问项目。任何项目都可以多次插入到数组中。数组保持其元素的顺序。
一个集合基本上只用于检查项目是否在集合中。这些项目没有顺序或索引的概念。你不能在一个集合中拥有两次。
如果一个数组想要检查它是否包含一个元素,它必须检查它的所有元素。集合旨在使用更快的算法。
你可以把集合想象成一个没有值的字典。
请注意,数组和集合不是唯一的数据结构。还有其他的,例如队列、堆栈、堆、斐波那契堆。我会推荐阅读一本关于算法和数据结构的书。
更多信息请参见wikipedia。
【讨论】:
contains 操作的复杂度是O(n)。不在数组中时的比较次数为n。对象在数组中时的平均比较次数为n/2。即使找到对象,性能也很糟糕。
NSArrays 比 NSSets 具有其他速度优势。与往常一样,这是一种权衡。
NSOrderedSet 在 iOS 5+ 中可用,因此主要区别在于您是否想要数据结构中的重复对象。
【讨论】:
主要区别已经在其他答案中给出。
我只想指出,由于集合和字典的实现方式(即使用哈希),应注意不要将可变对象用作键。
如果一个键发生了变异,那么哈希值也会(可能)发生变化,指向哈希表中的不同索引/存储桶。原始值不会被删除,并且在枚举或询问结构的大小/计数时实际上会被考虑在内。
这可能会导致一些非常难以定位的错误。
【讨论】:
NSArray *Arr;
NSSet *Nset;
Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];
NSLog(@"%@",Arr);
NSLog(@"%@",Nset);
数组
2015-12-04 11:05:40.935 [598:15730] (1, 2, 3, 4, 2, 1)
集合
2015-12-04 11:05:43.362 [598:15730] { ( 3, 1, 2, 5 )}
【讨论】:
NSArray:
NSSet:
【讨论】:
Here 你可以找到NSArray 和NSSet 数据结构的相当全面的比较。
小结:
是的,NSArray 比 NSSet 简单地保持和迭代更快。构建速度快 50%,迭代速度快 500%。教训:如果您只需要迭代内容,请不要使用 NSSet。
当然,如果您需要测试是否包含,请努力避免使用 NSArray。即使你需要迭代和包含测试,你可能仍然应该选择一个 NSSet。如果您需要保持集合有序并测试是否包含,那么您应该考虑保留两个集合(一个 NSArray 和一个 NSSet),每个集合都包含相同的对象。
NSDictionary 的构造比 NSMapTable 慢——因为它需要复制关键数据。它通过更快的查找来弥补这一点。当然,两者的能力不同,所以大多数时候,应该根据其他因素做出决定。
【讨论】:
当访问速度至关重要且顺序无关紧要时,您通常会使用 Set,或者由其他方式(通过谓词或排序描述符)确定。例如,当通过一对多关系访问托管对象时,Core Data 使用集合
【讨论】:
只是为了添加一点,我有时使用 set 来从数组中删除重复项,例如:-
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
【讨论】: