4

尽管,我遍历了以下NSSetNSMutableArrayNSFastEnumeration文档,但我无法为下面提到的场景找到令人满意的来源:

在这里,NSMutableArrayNSArray包含NSSet同样的 10000000 个对象。

for (NSString *strIn in MutableArray) //NSMutableArray
{
    // same Implementation
}
NSLog(@"Time for Mutable Array  %d Iteration : %f",ObjectCount,[[NSDate date]timeIntervalSinceDate:startDate]);
startDate = [NSDate date];
for (NSString *strIn in array)  //NSArray
{
    // same Implementation
}
NSLog(@"Time for  NSArray  %d Iteration : %f",ObjectCount,[[NSDate date]timeIntervalSinceDate:startDate]);
startDate = [NSDate date];
for (NSString *strIn in Set) //NSSet
{
    // same Implementation
}
NSLog(@"Time for Set  %d Iteration : %f",ObjectCount,[[NSDate date]timeIntervalSinceDate:startDate]);

输出如下:

10000000 次迭代的时间NSMutableArray :0.048785

10000000 次迭代的时间NSArray :0.390537

10000000 次迭代的时间NSSet :4.684203

NSSet为什么和NSArray迭代时间之间存在如此巨大的差异。

请彻底回答您的问题。

编辑:我发现上述迭代时间背后的实际原因是因为数组和 Set 中的计数不相等。我在这里发布了实际问题。另外,我可以在这里发布相同的内容,但该页面似乎太无证性质,而且原因背后的原因也有所偏差。再次感谢大家的回复。

4

2 回答 2

3

我不同意你的结果:

#import <Foundation/Foundation.h>

#define COLLECTION_SIZE 10000000

static NSString *randomString() {
    unichar buffer[18];
    NSUInteger size = (arc4random() % 12) + 6;
    for (NSUInteger i = 0; i < size; i++) {
        buffer[i] = (arc4random() % 93) + '!';
    }
    return [[NSString alloc] initWithCharacters:buffer length:size];
}

static NSSet *createCollection(NSUInteger size) {
    NSMutableSet *collection = [[NSMutableSet alloc] init];
    for (NSUInteger i = 0; i < size; i++) {
        for (;;) {
            NSString *s = randomString();
            if (![collection member:s]) {
                [collection addObject:s];
                break;
            }
        }
    }
    return collection;
}

static NSTimeInterval timedIter(id<NSFastEnumeration> collection) {
    NSUInteger totalLength = 0;
    NSDate *startDate = [NSDate date];
    for (NSString *s in collection) {
        totalLength += [s length];
    }
    return [[NSDate date] timeIntervalSinceDate:startDate];
}

int main(int argc, const char **argv) {
    @autoreleasepool {
        NSSet *set = createCollection(COLLECTION_SIZE);
        NSArray *array = [set allObjects];
        NSMutableArray *mutArray = [[set allObjects] mutableCopy];

        NSLog(@"set iteration=%f", timedIter(set));
        NSLog(@"array iteration=%f", timedIter(array));
        NSLog(@"mutArray iteration=%f", timedIter(mutArray));
    }
    return 0;
}

$ clang -o itertime itertime.m -fobjc-arc -framework Foundation
$ ./itertime
2013-11-13 11:23:13.344 itertime[77576:707] set iteration=0.422592
2013-11-13 11:23:13.654 itertime[77576:707] array iteration=0.309387
2013-11-13 11:23:13.964 itertime[77576:707] mutArray iteration=0.309107
于 2013-11-13T11:23:38.150 回答
2

差别太大了。可能是这样,因为您已经发出了循环体。我只是对 10M NSNumbers 做了同样的事情,差异要小得多:

Time for __NSArrayM: 0.334106
Time for __NSArrayI: 0.335368
Time for __NSSetI: 0.373651

你应该提供循环体,因为现在真的很难说你为什么会有这么大的差异。

于 2013-11-13T11:05:00.840 回答