2008-08-28 44 views
15

我知道,如果你有一個循環,修改了循環的項目使用NSEnumerator一組是最好的方式,以確保您的代碼炸燬數,不過,我想想了解NSEnumerator類,只是一個老同學之間的性能折衷for循環NSEnumerator性能,相較於可可

回答

26

在Objective-C使用新for (... in ...)語法2.0通常是對集合進行迭代的最快方式,因爲它可以在堆棧上維護一個緩衝區並獲取批量的項目。

使用NSEnumerator通常是最慢的方法,因爲它常常被複制重複採集;對不可變的集合這可能是小(相當於-retain),但可變集合它可以導致創建一個不變的副本。

做自己的迭代 - 例如,使用-[NSArray objectAtIndex:] - 通常會介於兩者之間,因爲雖然不會有潛在的複製開銷,但也不會從基礎集合中獲取批對象。

(PS - 這個問題應該被標記爲Objective-C中,不C,因爲NSEnumerator是可可類和新for (... in ...)語法具體到Objective-C)。

2

他們都非常相似。在Objective-C 2.0中,大多數枚舉現在默認爲NSFastEnumeration,它爲集合中的每個對象創建一個緩衝區,然後它可以傳遞這些地址。您在經典for循環中保存的一步不必在循環內部每次調用objectAtIndex:i。您正在枚舉的集合的內部實現快速枚舉而不需要調用objectAtIndex:i method

的緩衝區是可以發生變異,你枚舉集合的部分原因,對象的地址會改變,並且建成將不再匹配緩衝區。

作爲獎金在2.0格式看起來漂亮經典的for循環:

for (Type newVariable in expression) { 
    stmts 
} 

閱讀下列文件建立深究下去: NSFastEnumeration Protocol Reference

+0

@Jeff阿特伍德,該鏈接並沒有爲我工作。相反,我只是安裝了Xcode 4.我在Xcode的文檔和API參考中搜索了「NSFastEnumeration」以查找NSFastEnumeration協議參考。 – ma11hew28 2011-04-17 03:22:48

+0

@matt在未來點擊「編輯」,使我們的同路人更好的職位。我不做任何iOS開發.. :) – 2011-04-17 03:32:35

5

運行試了幾次後,結果幾乎相同。每個測量塊連續運行10次。

在我的情況下,結果以最快的速度最慢:

  1. 的for..in(testPerformanceExample3)(0.006秒)
  2. 雖然(testPerformanceExample4)(0.026秒)
  3. 對於(;;)(testPerformanceExample1)(0.027秒)
  4. 枚舉塊(testPerformanceExample2)(0.067秒)

for和while循環幾乎是相同的。

comparation between iterations

tmpNSArray其含有從0 1個百萬個對象到999999

- (NSArray *)createArray 
{ 
    self.tmpArray = [NSMutableArray array]; 
    for (int i = 0; i < 1000000; i++) 
    { 
     [self.tmpArray addObject:@(i)]; 
    } 
    return self.tmpArray; 
} 

整個代碼:

ViewController.h

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController 

@property (strong, nonatomic) NSMutableArray *tmpArray; 
- (NSArray *)createArray; 

@end 

的ViewController .m

#import "ViewController.h" 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self createArray]; 
} 

- (NSArray *)createArray 
{ 
    self.tmpArray = [NSMutableArray array]; 
    for (int i = 0; i < 1000000; i++) 
    { 
     [self.tmpArray addObject:@(i)]; 
    } 
    return self.tmpArray; 
} 

@end 

MyTestfile.m

#import <UIKit/UIKit.h> 
#import <XCTest/XCTest.h> 

#import "ViewController.h" 

@interface TestCaseXcodeTests : XCTestCase 
{ 
    ViewController *vc; 
    NSArray *tmp; 
} 

@end 

@implementation TestCaseXcodeTests 

- (void)setUp { 
    [super setUp]; 
    vc = [[ViewController alloc] init]; 
    tmp = vc.createArray; 
} 

- (void)testPerformanceExample1 
{ 
    [self measureBlock:^{ 
     for (int i = 0; i < [tmp count]; i++) 
     { 
      [tmp objectAtIndex:i]; 
     } 
    }]; 
} 

- (void)testPerformanceExample2 
{ 
    [self measureBlock:^{ 
     [tmp enumerateObjectsUsingBlock:^(NSNumber *obj, NSUInteger idx, BOOL *stop) { 
      obj; 
     }]; 
    }]; 
} 

- (void)testPerformanceExample3 
{ 
    [self measureBlock:^{ 
     for (NSNumber *num in tmp) 
     { 
      num; 
     } 
    }]; 
} 

- (void)testPerformanceExample4 
{ 
    [self measureBlock:^{ 
     int i = 0; 
     while (i < [tmp count]) 
     { 
      [tmp objectAtIndex:i]; 
      i++; 
     } 
    }]; 
} 

@end 

欲瞭解更多信息,請訪問:Apples "About Testing with Xcode"