1

検討:

- (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) ;
}

これは以下を出力します:

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

これはenumerateObjectsUsingBlock、通常の反復よりも 4 倍程度遅いことを示しています。

どちらか一方をいつ使用しますか?enumerateObjectsUsingBlockそのコストに見合った「付加価値」とは何か?

4

1 に答える 1

4

Mattt Thompson は、 NSHipsterに、Objective-C を反復処理するさまざまな方法について素晴らしい投稿を書きました。

enumerateObjectsUsingBlock提供する付加価値は、オブジェクトのインデックスとNSEnumerationOptions:

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

マットの引用:

反復中に実際に数値インデックスが必要でない限り、ほとんどの場合、代わりに for/in NSFastEnumeration ループを使用する方が高速です。

(...)

繰り返しになりますが、高速列挙はブロック列挙よりもはるかに高速であることはほぼ確実ですが、ブロックの使用に慣れている場合は、これらのオプションが役立つ場合があります。

于 2013-08-05T04:09:15.800 に答える