Usei NSSets muitas vezes em meus aplicativos, mas nunca criei um sozinho.
Usei NSSets muitas vezes em meus aplicativos, mas nunca criei um sozinho.
Respostas:
Quando a ordem dos itens na coleção não é importante, os conjuntos oferecem melhor desempenho para localizar itens na coleção.
A razão é que um conjunto usa valores hash para encontrar itens (como um dicionário), enquanto um array tem que iterar todo o seu conteúdo para encontrar um objeto específico.
A imagem da Documentação da Apple o descreve muito bem:
Array
é uma sequência ordenada (a ordem é mantida quando você adiciona) de elementos
[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
é uma lista distinta (sem duplicatas) e não ordenada de elementos
[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]
A melhor resposta é a documentação da própria Apple .
A principal diferença é que se NSArray
trata de uma coleção ordenada e NSSet
de uma coleção não ordenada.
Existem vários artigos por aí que falam sobre a diferença de velocidade entre os dois, como este . Se você estiver iterando em uma coleção não ordenada, NSSet
é ótimo. No entanto, em muitos casos, você precisa fazer coisas que apenas um NSArray
pode fazer, então você sacrifica a velocidade por essas habilidades.
NSSet
NSArray
Isso é tudo que realmente importa! Deixe-me saber se isso ajudar.
NSSet
por causa da indexação. É comum usar duas estruturas de dados diferentes para os mesmos dados. Ou você constrói e indexa nesse array :) Mas então é melhor usar um banco de dados que já o tenha implementado.
NSSet
e NSArray
, minha resposta é precisa e completa. Sim, você pode construir outras estruturas de dados, mas estou apenas comparando essas duas.
NSArray
e de alguma funcionalidade de NSSet
, a resposta correta não é "usar NSArray
e sacrificar o desempenho". A resposta é combinar ambos ou usar uma estrutura de dados diferente.
Uma matriz é usada para acessar itens por seu índice. Qualquer item pode ser inserido na matriz várias vezes. As matrizes mantêm a ordem de seus elementos.
Um conjunto é usado basicamente apenas para verificar se o item está na coleção ou não. Os itens não têm conceito de ordem ou indexação. Você não pode ter um item em um conjunto duas vezes.
Se um array deseja verificar se contém um elemento, ele deve verificar todos os seus itens. Os conjuntos são projetados para usar algoritmos mais rápidos.
Você pode imaginar um conjunto como um dicionário sem valores.
Observe que array e set não são as únicas estruturas de dados. Existem outros, por exemplo, Fila, Pilha, Pilha, Pilha de Fibonacci. Eu recomendaria a leitura de um livro sobre algoritmos e estruturas de dados.
Veja wikipedia para mais informações.
contains
operação é O(n)
. Número de comparações quando não está na matriz n
. O número médio de comparações quando o objeto está na matriz é n/2
. Mesmo que o objeto seja encontrado, o desempenho é péssimo.
NSArray
s têm outras vantagens de velocidade em relação aos NSSet
s. Como sempre, é uma troca.
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);
a matriz
2015-12-04 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)
o conjunto
2015-12-04 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}
As principais diferenças já foram dadas em outras respostas.
Gostaria apenas de observar que, devido à maneira como os conjuntos e os dicionários são implementados (ou seja, usando hashes), deve-se ter cuidado para não usar objetos mutáveis para as chaves.
Se uma chave sofrer mutação, o hash (provavelmente) também mudará, apontando para um índice / depósito diferente na tabela hash. O valor original não será excluído e será levado em consideração ao enumerar ou solicitar à estrutura seu tamanho / contagem.
Isso pode levar a alguns bugs muito difíceis de localizar.
Aqui você pode encontrar uma comparação bastante completa das estruturas de dados NSArray
e NSSet
.
Conclusões curtas:
Sim, o NSArray é mais rápido do que o NSSet para simplesmente segurar e iterar. Tão pouco quanto 50% mais rápido para construir e até 500% mais rápido para iterar. Lição: se você só precisa iterar o conteúdo, não use um NSSet.
Claro, se você precisar testar para inclusão, trabalhe duro para evitar NSArray. Mesmo se você precisar de testes de iteração e inclusão, provavelmente ainda deve escolher um NSSet. Se você precisa manter sua coleção ordenada e também testar para inclusão, você deve considerar manter duas coleções (um NSArray e um NSSet), cada uma contendo os mesmos objetos.
NSDictionary é mais lento para construir do que NSMapTable - uma vez que precisa copiar os dados-chave. Isso compensa por ser mais rápido de pesquisar. Obviamente, os dois têm capacidades diferentes, portanto, na maioria das vezes, essa determinação deve ser feita com base em outros fatores.
Normalmente, você usaria um Conjunto quando a velocidade de acesso fosse essencial e a ordem não importasse ou fosse determinada por outros meios (por meio de um predicado ou descritor de classificação). Core Data, por exemplo, usa conjuntos quando objetos gerenciados são acessados por meio de um relacionamento para muitos
Apenas para adicionar um pouco, eu uso set às vezes apenas para remover duplicatas da matriz como: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values