Help us understand the problem. What is going on with this article?

【NSDictionary】高速列挙for VS enumerateKeysAndObjectsUsingBlockでの処理速度対決、実際どっちもどっち説

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を活用するべき。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした