欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

iOS_NSArray和NSDictionary的遍历耗时对比

程序员文章站 2022-07-15 08:18:54
...

网上也有很多类似的描述对比说明文章,基本上是理论,还是实践比较靠谱。该文章为自己的测试结果记录,仅供参考。

        // 装载数据
        NSMutableDictionary *dataDict = [NSMutableDictionary dictionary];
        NSMutableArray<NSNumber *> *dataArray = [NSMutableArray array];
        for (NSInteger i = 0; i <= 1000000; i++) {// 插入大量数据,增加遍历耗时方便观察
            [dataDict setObject:[NSNumber numberWithInteger:i] forKey:[NSString stringWithFormat:@"%ld", i]];
            [dataArray addObject:[NSNumber numberWithInteger:i]];
        }
        
        // array耗时测试
        CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
        for (NSInteger i = 0; i < dataArray.count; i++) {
            NSNumber *num = dataArray[i];
            if (num.integerValue == 75000) break;
        }
        CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
        NSLog(@"for循环查找耗时:%f", end - start);

        start = CFAbsoluteTimeGetCurrent();
        for (NSNumber *num in dataArray) {
            if (num.integerValue == 75000) break;
        }
        end = CFAbsoluteTimeGetCurrent();
        NSLog(@"for in查找耗时:%f", end - start);
        
        start = CFAbsoluteTimeGetCurrent();
        [dataArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (obj.integerValue == 75000) *stop = YES;
        }];
        end = CFAbsoluteTimeGetCurrent();
        NSLog(@"顺序遍历数组查找耗时:%f", end - start);
        
        start = CFAbsoluteTimeGetCurrent();
        [dataArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (obj.integerValue == 75000) *stop = YES;
        }];
        end = CFAbsoluteTimeGetCurrent();
        NSLog(@"倒序遍历数组查找耗时:%f", end - start);

        // dictionary耗时测试
        start = CFAbsoluteTimeGetCurrent();
        NSNumber *num = dataDict[@"75000"];
        if (num.integerValue == 75000) NSLog(@"find value");
        end = CFAbsoluteTimeGetCurrent();
        NSLog(@"key value查找耗时:%f", end - start);

        start = CFAbsoluteTimeGetCurrent();
        [dataDict enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(id  _Nonnull key, NSNumber *  _Nonnull obj, BOOL * _Nonnull stop) {
            if (obj.integerValue == 75000) *stop = YES;
        }];
        end = CFAbsoluteTimeGetCurrent();
        NSLog(@"顺序遍历字典查找耗时:%f", end - start);

        start = CFAbsoluteTimeGetCurrent();
        [dataDict enumerateKeysAndObjectsWithOptions:NSEnumerationReverse usingBlock:^(id  _Nonnull key, NSNumber *  _Nonnull obj, BOOL * _Nonnull stop) {
            if (obj.integerValue == 75000) *stop = YES;
        }];
        end = CFAbsoluteTimeGetCurrent();
        NSLog(@"倒序遍历字典查找耗时:%f", end - start);

运行结果:(该值只是多次测试的其中一次结果。多次测试,除了具体值有变化,总体的快慢表现没变化)

for循环查找耗时:0.002143
for in查找耗时:0.000993
顺序遍历数组查找耗时:0.020580
倒序遍历数组查找耗时:0.038421
find value
key value查找耗时:0.000074
顺序遍历字典查找耗时:0.051333
倒序遍历字典查找耗时:0.016233

小结:

很明显,如果需要用来判断某个值是否存在,可以的话,使用keyValue的方式是最快的。另外,keyValue的值是个幸运数,有可能比测试结果相差更多也有可能更少,具体原因大家去了解一下array和dictionary的内存知识,太底层我不是很了解就不解释了,免得误导。