for構文の例
for (id key in dict){
id obj = [dict valueForKey:key];
}
enumerateKeysAndObjectsUsingBlockの例
[dict enumerateKeysAndObjectsUsingBlock:
^(id key, id object, BOOL *stop) {
}
];
以前はfor構文を使っていましたが、enumerateKeysAndObjectsUsingBlock
の存在を
知ったので処理速度の差があるのか今回計測してみました。
テストコード
int main(int argc, char * argv[]) {
@autoreleasepool {
int searchTarget = 100000;
NSMutableDictionary *dict = [NSDictionary dictionary].mutableCopy;
for(int i=0; i<searchTarget; i++){
NSString *key = [NSString stringWithFormat:@"%d番目",i];
dict[key] = key ;
}
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = @"YYYY-MM-dd HH:mm:ss.SSS";
NSLog(@"SEARCH_START01_%@",[dateFormatter stringFromDate:date]);
//パターン1:高速列挙
for (id key in dict){
id obj = [dict valueForKey:key];
if([obj isEqualToString:[NSString stringWithFormat:@"%d番目",searchTarget-1]]){
NSLog(@"SEARCH_HIT01_%@",[dateFormatter stringFromDate:[NSDate date]]);
}
}
NSLog(@"SEARCH_START02_%@",[dateFormatter stringFromDate:[NSDate date]]);
//パターン2:enumerateKeysAndObjectsUsingBlock
[dict enumerateKeysAndObjectsUsingBlock:
^(id key, id object, BOOL *stop) {
if([object isEqualToString:[NSString stringWithFormat:@"%d番目",searchTarget-1]]){
NSLog(@"SEARCH_HIT02_%@",[dateFormatter stringFromDate:[NSDate date]]);
}
}];
}
}
内容を解説すると、2020-02-12 22:34:39.728
こんな感じでログが出ます。
辞書を1000個key-Value
を生成して1000個目が取り出せた段階でログが出て終わりになります。
その結果をふまえて記事を作ってみました。
START-HITの差で計測します。
結果
//高速列挙
SEARCH_START01_2020-02-12 22:34:39.728
SEARCH_HIT01_2020-02-12 22:34:39.776 //差:0.48
//enumerateKeysAndObjectsUsingBlock
SEARCH_START02_2020-02-12 22:34:39.895
SEARCH_HIT02_2020-02-12 22:34:39.922 //差:0.27
10万件だと処理時間が約半分になるのですね。。
それでは100件でみてみましょう。
100件
//高速列挙
SEARCH_START01_2020-02-12 22:46:26.243
SEARCH_HIT01_2020-02-12 22:46:26.275 //差:0.32
//enumerateKeysAndObjectsUsingBlock
SEARCH_START02_2020-02-12 22:46:26.276
SEARCH_HIT02_2020-02-12 22:46:26.276 //差:0.00
流石に//差:0.00
は嘘臭いですけど何回やっても結果は変わりませんでした。
結論
for構文(高速列挙)ではなくてenumerateKeysAndObjectsUsingBlockを活用するべき。