當遇到大數據量需要遍歷的時候,不得不考慮遍歷的效率問題。研究了一下數組遍歷方法和效率。總的來說,循環遍歷有這么幾種:枚舉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 < 枚舉