遍历的目的是获取集合中的某个对象或执行某个操作,所以能满足这个条件的方法都可以作为备选:
1.for
2.for...in (NSFastEnumeration)
3.makeObjectsPerformSelector
4.kvc集合运算符
5.enumerateObjectsUsingBlock
6.enumerateObjectsWithOptions(NSEnumerationConcurrent)
7.dispatch_apply
以OC中常用为例
NSArray *arr = @[@"1",@"2",@"3"];
- for...in
for (NSString *str in arr) {
NSLog(@"For..in:%@",str);
}
- enumerateObjectsUsingBlock
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"enumerate:%@",obj);
}];
- enumerateObjectsWithOptions
[arr enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"Options:%@:%zd",obj,idx);
}];
- dispatch_apply
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/* ! dispatch_apply函数说明
*
* @brief dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联API
* 该函数按指定的次数将指定的Block追加到指定的Dispatch Queue中,并等到全部的处理执行结束
*
* @param count 指定重复次数 指定testArr.count
* @param queue 追加对象的Dispatch Queue
* @param index 带有参数的Block, index的作用是为了按执行的顺序区分各个Block
*
*/
dispatch_apply(arr.count, queue, ^(size_t index) {
NSLog(@"dispatch:%@",arr[index]);
});
代码可读性和效率权衡
100对象遍历操作 | 1000000对象遍历操作 | 100对象遍历执行一个很费时的操作 | |
---|---|---|---|
经典for循环 | 0.001355 | 1.246721 | 1.106567 |
for in (NSFastEnumeration) | 0.002308 | 0.025955 | 1.102643 |
makeObjectsPerformSelector | 0.001120 | 0.068234 | 1.103965 |
kvc集合运算符(@sum.number) | 0.004272 | 21.677246 | N/A |
enumerateObjectsUsingBlock | 0.001145 | 0.586034 | 1.104888 |
enumerateObjectsWithOptions (NSEnumerationConcurrent) | 0.001605 | 0.722548 | 0.554670 |
dispatch_apply(Concurrent) | 0.001380 | 0.607100 | 0.554858 |
- 使用选择
- 在集合内元素不多时,经典for循环的效率要比forin要高,但是从代码可读性上来看,就远不如forin看着更顺畅
- 对于耗时且顺序无关的遍历,使用并发版本
原文地址:blog.sunnyxx.com