3

私のアプリケーションは、2つの方法で接触しているすべての人を読み取ります。

forループ:

    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent ();
    long count = macContact.addressBook.people.count;
    for(int i=0;i<count;++i){
        ABPerson *person = [macContact.addressBook.people objectAtIndex:i];
        NSLog(@"%@",person);
    }
    NSLog(@"%f",CFAbsoluteTimeGetCurrent() - startTime);

for-each

    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent ();
    for(ABPerson *person in macContact.addressBook.people){
        NSLog(@"%@",person);
    }
    NSLog(@"%f",CFAbsoluteTimeGetCurrent() - startTime);

for-eachはaddressBookで5000人を列挙するのに4秒しかかかりませんでしたが、for-loopは同じ仕事をするのに10分かかりました。

なぜパフォーマンスに大きな違いがあるのか​​知りたいのですが?

4

1 に答える 1

5

パフォーマンスの違いは、ほぼ確実にmacContact.addressBook.peopleパーツに関係しています。これは、forループを介して毎回呼び出していますが、for-eachループを使用して1回だけ呼び出しています。addressBookまたはpeopleプロパティのいずれかがキャッシュされたデータを返すのではなく、毎回新しいデータを返すと推測しています。

使ってみてください

NSArray *people = macContact.addressBook.people;
for (int i = 0; i < [people count]; i++) {
    NSLog(@"%@", [people objectAtIndex:i];
}

おそらく、パフォーマンスは非常に似ていることに気付くでしょう。


とは言うものの、for-eachは一般的なものよりも高速です。その理由は、forループがループ()を通過するたびにメソッドsendを呼び出すの-objectAtIndex:に対し、for-eachはオブジェクトを大きなバッチで取得することで、オブジェクトをはるかに効率的にフェッチできるためです。

OSの最新バージョンでは、さらに一歩進んで、ブロックベースの列挙方法を使用できます。これは次のようになります

[macContact.addressBook.people enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL stop){
    NSLog(@"%@", obj);
}];

NSArrayの場合、これはfor-eachループと非常によく似たパフォーマンスを持つはずです。辞書などの他のデータ構造の場合、このスタイルはキーとともに値をフェッチできるため、より高速になります(一方、for-eachはキーのみを提供し、メッセージ送信を使用して値を取得する必要があります)。

于 2012-08-24T04:50:35.683 に答える