Frage

Ich weiß, dass, wenn Sie haben eine Schleife, die ändert die Anzahl der Elemente in der Schleife, mit der NSEnumerator auf ein einstellen, ist der beste Weg, um sicherzustellen, dass Ihr code in die Luft sprengt, jedoch würde ich gerne verstehen, die performance-Unterschiede zwischen den NSEnumerator Klasse und nur eine old-school-Schleife

War es hilfreich?

Lösung

Mit dem neuen for (... in ...) syntax in Objective-C 2.0 ist in der Regel der Schnellste Weg zum Durchlaufen einer Sammlung, weil es pflegen einen Puffer auf dem stack und erhalten Stapel von Elementen in es.

Verwendung NSEnumerator ist in der Regel der langsamste Weg, weil es oft kopiert die collection iterieren;für unveränderliche Sammlungen diese kann Billig sein, (entspricht -retain), aber für die veränderlichen collections, die es verursachen kann, eine unveränderliche Kopie erstellt werden.

Tun, Ihre eigene iteration — zum Beispiel mit -[NSArray objectAtIndex:] — wird im Allgemeinen fallen irgendwo dazwischen, denn während Sie nicht das Potenzial haben, kopieren overhead, wirst du auch nicht bekommen Chargen von Objekten aus der zugrunde liegenden Auflistung.

(PS - Diese Frage sollte tagged as Objective-C, nicht C, da NSEnumerator ist eine Cocoa-Klasse und der neue for (... in ...) syntax ist spezifisch für Objective-C.)

Andere Tipps

Nach Durchführung des Tests mehrmals, das Ergebnis ist fast das gleiche.Jede Maßnahme block läuft 10-mal hintereinander.

Das Ergebnis ist in meinem Fall von der schnellsten zur langsamsten:

  1. For..in - (testPerformanceExample3) (0.006 Sekunden)
  2. Während (testPerformanceExample4) (0.026 Sek)
  3. For(;;) (testPerformanceExample1) (0.027 Sekunden)
  4. Enumeration block (testPerformanceExample2) (0.067 Sek.)

Die for-und die while-Schleife ist fast das gleiche.

comparation between iterations

Die tmp ist ein NSArray enthält 1 million Objekte von 0 bis 999999.

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

Der gesamte code:

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

Für weitere Informationen besuchen Sie: Äpfel "zum Testen mit Xcode"

Sie sind sich sehr ähnlich.Mit Objective-C 2.0 meisten Aufzählungen, die jetzt standardmäßig NSFastEnumeration das schafft einen Puffer, mit dem die Adressen auf jedes Objekt in der Sammlung, dann kann es liefern.Der eine Schritt, den Sie speichern über die klassische for-Schleife ist nicht mit zu nennen objectAtIndex:i jedes mal in der Schleife.Die Interna der Kollektion, die Sie aufzählen Umsetzung schnell Aufzählung heraus aufrufen objectAtIndex:i method.

Der Puffer ist ein Teil des Grundes, dass Sie können nicht mutieren einer Sammlung, wie Sie auflisten, die Adresse der Objekte ändern wird und der Puffer, der gebaut wurde, wird nicht mehr übereinstimmen.

Als bonus-format in 2.0 sieht so schön, wie die klassische for-Schleife:

for ( Type newVariable in expression ) { 
    stmts 
}

Lesen Sie die folgenden documentaion, um tiefer zu gehen:NSFastEnumeration-Protokoll-Referenz

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top