集合類對象(NSArray、NSDictionary、NSSet及其子類)在Objective-C中十分常見。經常會有遍歷集合中所有對象的需求,Objective-C中遍歷集合中對象的方法有三種:
-
C語言的for循環遍歷;
-
Objective-C的快速枚舉;
-
集合對象的枚舉塊語法。
爲了測試以上三種枚舉方法消耗的時間,我寫了一個小程序,對含有1萬個元素的數組進行打印操作,看看分別都消耗了多長時間。核心代碼如下:
Large Enumeration Test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
NSUInteger totalCount = 10000;
NSMutableArray *array = [NSMutableArray arrayWithCapacity:totalCount];
//create an array including 10000 elements
for (int i = 0; i<totalCount; i++) {
array[i] = [@(i) stringValue];
}
//C Language For Loop Enumeration
CFTimeInterval start1 = CACurrentMediaTime();
for (int j = 0; j< totalCount; j++) {
NSLog(@"%@",array[j]);
}
CFTimeInterval end1 = CACurrentMediaTime();
NSLog(@"C Language For Loop method %f",end1 - start1);
//Objective-C Fast Enumeration
CFTimeInterval start2 = CACurrentMediaTime();
for (NSString *string in array) {
NSLog(@"%@",string);
}
CFTimeInterval end2 = CACurrentMediaTime();
NSLog(@"Objective-C Fast Enumeration method %f",end2 - start2);
//Objective-C Block Enumeration
CFTimeInterval start3 = CACurrentMediaTime();
[array enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString * obj, NSUInteger idx, BOOL *stop) {
NSLog(@"%@",obj);
}];
CFTimeInterval end3 = CACurrentMediaTime();
NSLog(@"Objective-C Block Enumeration method %f",end3 - start3);
|
其中CACurrentMediaTime()是一個返回系統時間的函數(蘋果參考文檔),可以通過結束時間減去開始時間計算代碼所消耗的時間。(附:在Mac終端中輸入w可以查詢機器已經運行的時間信息,w屬於Unix命令。)
部分運行結果:
Consume Time Results
1
2
3
|
2014-03-11 15:04:41.522 testspeed[19780:70b] C Language For Loop method 7.750710
2014-03-11 15:04:47.847 testspeed[19780:70b] Objective-C Fast Enumeration method 6.323673
2014-03-11 15:04:53.715 testspeed[19780:70b] Objective-C Block Enumeration method 5.866547
|
從以上結果可以看出,語法塊的枚舉耗時最短,快速枚舉次之,for循環最慢。語法塊枚舉快的主要原因是枚舉options中採用了NSEnumerationConcurrent,也就是並行處理,充分發揮了多核心的優勢。當然這麼做會導致輸出順序錯亂,如果需求對順序要求嚴格,就不能使用這個選項。