Réponses:
Lorsque l'ordre des éléments de la collection n'est pas important, les ensembles offrent de meilleures performances pour rechercher des éléments de la collection.
La raison en est qu'un ensemble utilise des valeurs de hachage pour trouver des éléments (comme un dictionnaire) tandis qu'un tableau doit parcourir tout son contenu pour trouver un objet particulier.
L'image de la documentation Apple le décrit très bien:
Array
est une séquence ordonnée (l'ordre est conservé lorsque vous ajoutez)
[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
est une liste d'éléments distincts (pas de doublons) et non ordonnés
[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]
La meilleure réponse est à cela est la propre documentation d'Apple .
La principale différence est qu'il NSArray
s'agit d'une collection ordonnée et NSSet
d'une collection non ordonnée.
Il existe plusieurs articles qui parlent de la différence de vitesse entre les deux, comme celui-ci . Si vous parcourez une collection non ordonnée, NSSet
c'est génial. Cependant, dans de nombreux cas, vous devez faire des choses que seul un NSArray
peut faire, vous sacrifiez donc la vitesse pour ces capacités.
NSSet
NSArray
C'est tout ce qu'il y a vraiment à faire! Faites-moi savoir si cela vous a été utile.
NSSet
pour l'indexation. Il est courant d'utiliser deux structures de données différentes pour les mêmes données. Ou vous construisez et indexez sur ce tableau :) Mais alors il est préférable d'utiliser une base de données qui l'a déjà implémentée.
NSSet
et NSArray
, ma réponse est exacte et complète. Oui, vous pouvez créer d'autres structures de données, mais je compare simplement ces deux.
NSArray
et de certaines fonctionnalités de NSSet
, la bonne réponse n'est pas "utiliser NSArray
et sacrifier les performances". La réponse est de combiner les deux ou d'utiliser une structure de données différente.
Un tableau est utilisé pour accéder aux éléments par leur index. Tout élément peut être inséré dans le tableau plusieurs fois. Les tableaux conservent l'ordre de leurs éléments.
Un ensemble est essentiellement utilisé uniquement pour vérifier si l'élément est dans la collection ou non. Les articles n'ont aucune notion de commande ou d'indexation. Vous ne pouvez pas avoir un élément dans un ensemble deux fois.
Si un tableau veut vérifier s'il contient un élément, il doit vérifier tous ses éléments. Les ensembles sont conçus pour utiliser des algorithmes plus rapides.
Vous pouvez imaginer un ensemble comme un dictionnaire sans valeurs.
Notez que tableau et ensemble ne sont pas les seules structures de données. Il y en a d'autres, par exemple Queue, Stack, Heap, Fibonacci's Heap. Je recommanderais de lire un livre sur les algorithmes et les structures de données.
Voir wikipedia pour plus d'informations.
contains
opération est O(n)
. Le nombre de comparaisons lorsqu'il n'est pas dans le tableau est n
. Le nombre moyen de comparaisons lorsque l'objet est dans le tableau est n/2
. Même si l'objet est trouvé, les performances sont horribles.
NSArray
s présentent d'autres avantages de vitesse par rapport aux NSSet
s. Comme toujours, c'est un compromis.
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);
le tableau
04/12/2015 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)
l'ensemble
04/12/2015 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}
Les principales différences ont déjà été données dans d'autres réponses.
Je voudrais juste noter qu'en raison de la façon dont les ensembles et les dictionnaires sont implémentés (c'est-à-dire en utilisant des hachages), il faut faire attention à ne pas utiliser d'objets mutables pour les clés.
Si une clé est mutée, le hachage changera (probablement) aussi, pointant vers un autre index / compartiment dans la table de hachage. La valeur d'origine ne sera pas supprimée et sera effectivement prise en compte lors de l'énumération ou de la demande à la structure de sa taille / nombre.
Cela peut conduire à des bogues très difficiles à localiser.
Ici vous trouverez une comparaison assez approfondie des NSArray
et NSSet
datastructures.
Conclusions brèves:
Oui, NSArray est plus rapide que NSSet pour simplement tenir et itérer. Aussi peu que 50% plus rapide pour la construction et jusqu'à 500% plus rapide pour l'itération. Leçon: si vous avez seulement besoin d'itérer le contenu, n'utilisez pas de NSSet.
Bien sûr, si vous devez tester l'inclusion, travaillez dur pour éviter NSArray. Même si vous avez besoin à la fois de tests d'itération et d'inclusion, vous devriez probablement toujours choisir un NSSet. Si vous avez besoin de garder votre collection ordonnée et de tester également l'inclusion, vous devriez envisager de conserver deux collections (un NSArray et un NSSet), chacune contenant les mêmes objets.
NSDictionary est plus lent à construire que NSMapTable - car il doit copier les données clés. Cela compense cela en étant plus rapide à rechercher. Bien sûr, les deux ont des capacités différentes, donc la plupart du temps, cette détermination doit être faite sur d'autres facteurs.
Vous utiliserez généralement un ensemble lorsque la vitesse d'accès est essentielle et que l'ordre n'a pas d'importance , ou est déterminé par d'autres moyens (via un prédicat ou un descripteur de tri). Core Data, par exemple, utilise des ensembles lorsque des objets gérés sont accessibles via une relation à plusieurs
Juste pour en ajouter un peu, j'utilise parfois set juste pour supprimer les doublons du tableau comme: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values