Ho utilizzato NSSet molte volte nelle mie app, ma non ne ho mai creato uno da solo.
Ho utilizzato NSSet molte volte nelle mie app, ma non ne ho mai creato uno da solo.
Risposte:
Quando l'ordine degli elementi nella raccolta non è importante, i set offrono prestazioni migliori per la ricerca di elementi nella raccolta.
Il motivo è che un set usa valori hash per trovare elementi (come un dizionario) mentre un array deve iterare su tutto il suo contenuto per trovare un particolare oggetto.
L'immagine dalla documentazione di Apple lo descrive molto bene:
Array
è una sequenza di elementi ordinata (l'ordine viene mantenuto quando si aggiunge)
[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
è un elenco di elementi distinto (senza duplicati) e non ordinato
[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 migliore risposta a questa domanda è la documentazione di Apple .
La differenza principale è che NSArray
è per una raccolta ordinata e NSSet
per una raccolta non ordinata.
Ci sono diversi articoli là fuori che parlano della differenza di velocità tra i due, come questo . Se stai iterando attraverso una raccolta non ordinata, NSSet
è fantastico. Tuttavia, in molti casi, devi fare cose che solo un NSArray
può fare, quindi sacrifichi la velocità per quelle abilità.
NSSet
NSArray
Questo è tutto ciò che c'è davvero da fare! Fammi sapere se aiuta.
NSSet
per il bene dell'indicizzazione. È comune utilizzare due diverse strutture di dati per gli stessi dati. Oppure si crea e si indicizza su quell'array :) Ma poi è meglio usare un DB che lo abbia già implementato.
NSSet
e NSArray
, la mia risposta è accurata e completa. Sì, puoi creare altre strutture di dati, ma sto solo confrontando queste due.
NSArray
e di alcune funzionalità NSSet
, la risposta corretta non è "usa NSArray
e sacrifica le prestazioni". La risposta è combinare entrambi o utilizzare una struttura dati diversa.
Un array viene utilizzato per accedere agli elementi in base al loro indice. Qualsiasi elemento può essere inserito più volte nell'array. Gli array mantengono l'ordine dei loro elementi.
Un set viene utilizzato fondamentalmente solo per verificare se l'elemento è nella collezione o meno. Gli articoli non hanno il concetto di ordine o indicizzazione. Non puoi avere un oggetto in un set due volte.
Se un array vuole controllare se contiene un elemento, deve controllare tutti i suoi elementi. I set sono progettati per utilizzare algoritmi più veloci.
Puoi immaginare un insieme come un dizionario senza valori.
Notare che array e set non sono le uniche strutture di dati. Ce ne sono altri, ad esempio Queue, Stack, Heap, Fibonacci's Heap. Consiglierei di leggere un libro sugli algoritmi e le strutture dati.
Vedi wikipedia per maggiori informazioni.
contains
dell'operazione è O(n)
. Il numero di confronti quando non è nell'array è n
. Il numero medio di confronti quando l'oggetto è nella matrice è n/2
. Anche se l'oggetto viene trovato, la prestazione è terribile.
NSArray
s ha altri vantaggi in termini di velocità rispetto a NSSet
s. Come sempre, è un compromesso.
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);
l'array
04/12/2015 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)
il set
04/12/2015 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}
Le principali differenze sono già state fornite in altre risposte.
Vorrei solo notare che a causa del modo in cui i set e i dizionari sono implementati (cioè usando gli hash), si dovrebbe fare attenzione a non usare oggetti mutabili per le chiavi.
Se una chiave viene modificata, anche l'hash cambierà (probabilmente), indicando un indice / bucket diverso nella tabella hash. Il valore originale non verrà eliminato e verrà effettivamente preso in considerazione quando si enumera o si chiede alla struttura la sua dimensione / conteggio.
Questo può portare ad alcuni bug davvero difficili da individuare.
Qui puoi trovare un confronto abbastanza approfondito delle strutture di dati NSArray
e NSSet
.
Brevi conclusioni:
Sì, NSArray è più veloce di NSSet per il semplice mantenimento e l'iterazione. Fino al 50% più veloce per la costruzione e fino al 500% più veloce per l'iterazione. Lezione: se hai solo bisogno di iterare i contenuti, non usare un NSSet.
Ovviamente, se devi testare l'inclusione, lavora sodo per evitare NSArray. Anche se hai bisogno sia di iterazione che di test di inclusione, dovresti comunque scegliere un NSSet. Se è necessario mantenere la raccolta ordinata e anche testarne l'inclusione, è opportuno considerare di conservare due raccolte (un NSArray e un NSSet), ciascuna contenente gli stessi oggetti.
NSDictionary è più lento da costruire rispetto a NSMapTable, poiché deve copiare i dati chiave. Compensa ciò essendo più veloce nella ricerca. Naturalmente, i due hanno capacità diverse, quindi la maggior parte delle volte questa determinazione dovrebbe essere fatta su altri fattori.
In genere si utilizza un Set quando la velocità di accesso è essenziale e l'ordine non è importante o è determinato con altri mezzi (tramite un predicato o un descrittore di ordinamento). Core Data, ad esempio, utilizza set quando si accede agli oggetti gestiti tramite una relazione a molti
Solo per aggiungerne un po ', a volte uso set solo per rimuovere i duplicati dall'array come: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values