回答:
コレクション内のアイテムの順序が重要ではない場合、セットを使用すると、コレクション内のアイテムを検索する際のパフォーマンスが向上します。
その理由は、セットはハッシュ値を使用してアイテム(辞書など)を見つけるのに対し、配列は特定のオブジェクトを見つけるためにコンテンツ全体を反復処理する必要があるためです。
Appleのドキュメンテーションからの画像はそれを非常によく説明しています:
Array
されて注文した要素のシーケンスを(あなたが追加したときに順序が維持されています)
[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];
[1, 2, 3, 4, 6, 4, 1, 2]
Set
されていない異なる(非重複)、順序付けられていない要素のリスト
[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];
[1, 2, 6, 4, 3]
これに対する最良の答えは、Apple自身のドキュメントです。
主な違いはNSArray
、順序付けられたコレクションとNSSet
順序付けられていないコレクションです。
この1つのように、2つの速度の違いについて述べた記事がいくつかあります。順序付けられていないコレクションを繰り返し処理する場合NSSet
は、すばらしいです。ただし、多くの場合、あなただけがNSArray
できることをする必要があるので、それらの能力の速度を犠牲にします。
NSSet
NSArray
これですべてです。問題が解決したかどうかをお知らせください。
NSSet
インデックス作成のために常に犠牲にする必要はありません。同じデータに対して2つの異なるデータ構造を使用するのが一般的です。または、その配列にビルドしてインデックスを付けます。
NSSet
そしてNSArray
、私の答えは正確かつ完全です。はい、他のデータ構造を構築できますが、私はこれら2つを比較しているだけです。
NSArray
との機能が必要な場合NSSet
、正解は「NSArray
パフォーマンスの使用と犠牲」ではありません。答えは、両方を組み合わせるか、異なるデータ構造を使用することです。
配列は、インデックスによってアイテムにアクセスするために使用されます。任意のアイテムを配列に複数回挿入できます。配列は要素の順序を管理します。
セットは基本的に、アイテムがコレクション内にあるかどうかを確認するためだけに使用されます。アイテムには、順序やインデックスの概念はありません。セット内のアイテムを2回持つことはできません。
配列に要素が含まれているかどうかを確認する場合は、そのすべての項目を確認する必要があります。セットは、より高速なアルゴリズムを使用するように設計されています。
値のない辞書のようなセットを想像できます。
配列とセットだけがデータ構造ではないことに注意してください。キュー、スタック、ヒープ、フィボナッチのヒープなど、他にもあります。アルゴリズムとデータ構造についての本を読むことをお勧めします。
詳細については、ウィキペディアを参照してください。
contains
操作の複雑さはO(n)
です。配列にない場合の比較数はn
です。オブジェクトが配列内にある場合の比較の平均数はn/2
です。オブジェクトが見つかったとしても、パフォーマンスはひどいです。
NSArray
sにはsに比べて他の速度上の利点がありNSSet
ます。いつものように、それはトレードオフです。
NSArray *Arr;
NSSet *Nset;
Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];
NSLog(@"%@",Arr);
NSLog(@"%@",Nset);
配列
2015-12-04 11:05:40.935 [598:15730](1、2、3、4、2、1)
セット
2015-12-04 11:05:43.362 [598:15730] {(3、1、2、5)}
ここでは、NSArray
とNSSet
データ構造のかなり完全な比較を見つけることができます。
短い結論:
はい、NSArrayはNSSetよりも高速に保持および反復できます。構築は50%程度速く、反復は500%程度速くなります。レッスン:コンテンツを反復するだけの場合は、NSSetを使用しないでください。
もちろん、包含をテストする必要がある場合は、NSArrayを回避するために一生懸命に作業してください。反復テストと包含テストの両方が必要な場合でも、おそらくNSSetを選択する必要があります。コレクションの順序を維持し、包含をテストする必要がある場合は、2つのコレクション(NSArrayとNSSet)を保持することを検討してください。それぞれに同じオブジェクトが含まれています。
NSDictionaryはNSMapTableよりも構築に時間がかかります—キーデータをコピーする必要があるためです。ルックアップが高速になることで、これを補います。もちろん、2つは異なる機能を備えているため、ほとんどの場合、この決定は他の要因で行う必要があります。
少しだけ追加するために、配列の重複を削除するために時々setを使用します:-
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values