質問

Consider:

- (void) testing {
    NSMutableArray * numbers = [NSMutableArray arrayWithCapacity:10000000] ;
    for (int i = 0 ; i < 10000000 ; ++i) {
        [numbers addObject:@(i)] ;
    }

    NSInteger (^sum)(NSInteger, NSInteger) = ^(NSInteger running, NSInteger n) {
        return running + n ;
    } ;

    double start = ::CACurrentMediaTime() ;
    __block NSInteger running = 0 ;
    for (NSNumber * n in numbers) {
        running = sum(running, [n integerValue]) ;
    }
    running = 0 ;
    double end1 = ::CACurrentMediaTime() ;
    [numbers enumerateObjectsUsingBlock:^(NSNumber * n, NSUInteger idx, BOOL *stop) {
        running = sum(running, [n integerValue]) ;
    }] ;
    double end2 = ::CACurrentMediaTime() ;

    ::NSLog(@"fastEnum: %0.3f, enumUsingBlock: %0.3f", end1-start, end2-end1) ;
}

This outputs:

2013-08-05 00:38:34.852 WC[48299:a0b] fastEnum: 0.341, enumUsingBlock: 1.358

This says that enumerateObjectsUsingBlock is 4x slower or so than regular iteration.

When does one use one or the other? What is the "added value" that enumerateObjectsUsingBlock provides that justifies its cost?

役に立ちましたか?

解決

Mattt Thompson wrote a great post on NSHipster about the many ways to iterate with Objective-C.

The added value that enumerateObjectsUsingBlock provides is giving the index of the object and NSEnumerationOptions:

enum {
   NSEnumerationConcurrent = (1UL << 0),
   NSEnumerationReverse = (1UL << 1),
};
typedef NSUInteger NSEnumerationOptions;

Quoting Mattt:

Unless you actually need the numerical index while iterating, it's almost always faster to use a for/in NSFastEnumeration loop instead.

(...)

Again, fast enumeration is almost certain to be much faster than block enumeration, but these options may be useful if you're resigned to using blocks.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top