当遇到大数据量需要遍历的时候,不得不考虑遍历的效率问题。研究了一下数组遍历方法和效率。总的来说,循环遍历有这么几种:枚举block,枚举器,dispatch_apply模拟,do-while,for-in,for这么几种。废话少说,上代码!
1.正序枚举block
[_array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%lu---%@",(unsigned long)idx,[_array objectAtIndex:idx]);
}];
2.乱序枚举block
//NSEnumerationReverse参数为倒序,NSEnumerationConcurrent参数为乱序
[_array enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%lu---%@",(unsigned long)idx,[_array objectAtIndex:idx]);
}];
3.枚举器
NSEnumerator *enumrator = [_array objectEnumerator];
id obj;
int k = 0;
while (obj = [enumrator nextObject]) {
NSLog(@"%d---%@",k,obj);
k++;
}
4.GCD的API
//并行,乱序
dispatch_apply(_array.count, dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"%zu---%@",index,[_array objectAtIndex:index]);
});
5.do-while / while
//do-while
int i = 0;
do {
NSLog(@"%d---%@",i,[_array objectAtIndex:i]);
i++;
} while (i < _array.count);
//while
while (i < _array.count) {
NSLog(@"%d---%@",i,[_array objectAtIndex:i]);
i++;
}
6.for-in
for (id obj in _array) {
NSLog(@"%@",obj);
}
7.for
for (int i = 0; i < _array.count; i++) {
NSLog(@"%d---%@",i,_array[i]);
}
以上,列举了遍历可以选择的方法,然鹅......到底哪个最快呢,于是采用了一个方法验证了一下:
首先,懒加载一个big数组。
- (NSMutableArray *)array {
if (!_array) {
_array = [NSMutableArray array];
for (int i = 0; i < 10000000; i ++) {
[_array addObject:[[NSObject alloc] init]];
}
}
return _array;
}
然后,像酱紫进行了验证。看控制台打印的结果,得到了3.674秒。其他方法不一一进行演示。
NSLog(@"start");
for (int i = 0; i < self.array.count; i++) {
}
NSLog(@"end");
分享一下我自测的结果(可能会有偏差,感兴趣可以自测一下试试)
1---5.552s 2---5.287s 3---5.227s 4---3.203 5---3.626s / 3.546s 6---3.016s 7---3.674s
所以:for-in < dispatch_apply < while < do-while < for < 枚举