سؤال

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