oc/object-c/ios哪种遍历NSArray/NSDictionary方式快?测试报告
做app的时候,总免不了要多次遍历数组或者字典。
究竟哪种遍历方式比较快呢?我做了如下测试:
首先定义测试用宏:
|
1
2
3
4
5
6
7
8
9
|
#define
MULogTimeintervalBegin(INFO) NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];\NSTimeInterval
duration = 0;\NSLog(@"MULogTimeintervalBegin:%@",
INFO)#define
MULogTimeintervalPauseAndLog(INFO) duration = [NSDate timeIntervalSinceReferenceDate] - start;\start
+= duration;\NSLog(@"%@:%f",
INFO, duration);\duration
= 0#define
TESTSCALE 100000 |
接着编写测试代码:
NSarray:
|
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
28
29
30
|
-
(void)testArray{ NSMutableArray*
testArray = [NSMutableArray
arrayWithCapacity:TESTSCALE]; for
(NSInteger
i = 1; i <= TESTSCALE; ++i) { [testArray
addObject:[NSString
stringWithFormat:@"%ld",
i]]; } NSLog(@"init:%ld",
[testArray count]); __block
NSMutableString*
sum = [NSMutableString
stringWithCapacity:TESTSCALE]; MULogTimeintervalBegin(@"ArrayTest"); NSUInteger
count = [testArray count]; for
(NSInteger
i = 0; i < count; ++i) { [sum
appendString:[testArray objectAtIndex:i]]; } [sum
setString:@""]; MULogTimeintervalPauseAndLog(@"for
statement"); for(NSString*
item in testArray) { [sum
appendString:item]; } [sum
setString:@""]; MULogTimeintervalPauseAndLog(@"for-in"); [testArray
enumerateObjectsUsingBlock:^(id
obj, NSUInteger
idx, BOOL
*stop) { [sum
appendString:obj]; }]; [sum
setString:@""]; MULogTimeintervalPauseAndLog(@"enumerateBlock");} |
NSDictionary:
|
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
|
-
(void)testDictionary
{ NSMutableDictionary*
testDic = [NSMutableDictionary
dictionaryWithCapacity:TESTSCALE]; for
(NSInteger
i = 1; i <= TESTSCALE; ++i) { [testDic
setObject:@"test"
forKey:[NSString
stringWithFormat:@"%ld",
i]]; } NSLog(@"init:%ld",
[testDic count]); __block
NSMutableString*
sum = [NSMutableString
stringWithCapacity:TESTSCALE]; MULogTimeintervalBegin(@"DictionaryTest"); for
(NSString*
object in [testDic allValues]) { [sum
appendString:object]; } [sum
setString:@""]; MULogTimeintervalPauseAndLog(@"for
statement allValues"); for
(id
akey in [testDic allKeys]) { [sum
appendString:[testDic objectForKey:akey]]; } [sum
setString:@""]; MULogTimeintervalPauseAndLog(@"for
statement allKeys"); [testDic
enumerateKeysAndObjectsUsingBlock:^(id
key, id
obj, BOOL
*stop) { [sum
appendString:obj]; }
]; MULogTimeintervalPauseAndLog(@"enumeration");} |
下面是测试结果:
Test Case '-[LoopTestTests testArray]' started.
2012-08-02 17:14:22.061 otest[388:303] init:100000
2012-08-02 17:14:22.062 otest[388:303] MULogTimeintervalBegin:ArrayTest
2012-08-02 17:14:22.075 otest[388:303]for statement:0.013108
2012-08-02 17:14:22.083 otest[388:303]for-in:0.008186
2012-08-02 17:14:22.095 otest[388:303] enumerateBlock:0.012290
Test Case '-[LoopTestTests testArray]' passed (0.165 seconds).
Test Case '-[LoopTestTests testDictionary]' started.
2012-08-02 17:14:22.273 otest[388:303] init:100000
2012-08-02 17:14:22.274 otest[388:303] MULogTimeintervalBegin:DictionaryTest
2012-08-02 17:14:22.284 otest[388:303] for statement allValues:0.010566
2012-08-02 17:14:22.307 otest[388:303] for statement allKeys:0.022377
2012-08-02 17:14:22.330 otest[388:303] enumeration:0.023914
Test Case '-[LoopTestTests testDictionary]' passed (0.217 seconds).
可以看出对于数组来说,for-in方式遍历速度是最快的,普通风格的for和block方式速度差不多。对于字典来说,allValues方式遍历最快,allKeys和block差不多。
那么,为什么会这样呢?
NSArray:
|
1
2
3
|
for
(NSInteger
i = 0; i < count; ++i) { [sum
appendString:[testArray objectAtIndex:i]];} |
这里由于存在:[objectAtIndex:i]这样的取操作,所以速度会有所下降。
而
|
1
2
3
|
for(NSString*
item in testArray) { [sum
appendString:item];} |
尽管也有取操作,但是绕开了oc的message机制,速度会快一点。也有可能是编译器为了for-in作了优化。
block为什么会慢一些这个有待研究。
NSDictionary:
|
1
2
3
|
for
(id
akey in [testDic allKeys]) { [sum
appendString:[testDic objectForKey:akey]];} |

浙公网安备 33010602011771号