Respuestas:
Cuando el orden de los elementos de la colección no es importante, los conjuntos ofrecen un mejor rendimiento para encontrar elementos en la colección.
La razón es que un conjunto usa valores hash para encontrar elementos (como un diccionario), mientras que una matriz tiene que iterar sobre todo su contenido para encontrar un objeto en particular.
La imagen de la documentación de Apple lo describe muy bien:
Array
es una secuencia ordenada (el orden se mantiene cuando agrega) 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
es una lista de elementos distinta (sin duplicados) y desordenada
[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 mejor respuesta es la propia documentación de Apple .
La principal diferencia es que NSArray
es para una colección ordenada y NSSet
es para una colección desordenada.
Hay varios artículos que hablan sobre la diferencia de velocidad entre los dos, como este . Si está iterando a través de una colección desordenada, NSSet
es genial. Sin embargo, en muchos casos, necesitas hacer cosas que solo uno NSArray
puede hacer, por lo que sacrificas la velocidad por esas habilidades.
NSSet
NSArray
¡Eso es todo lo que hay que hacer! Avísame si eso ayuda.
NSSet
por indexar. Es común utilizar dos estructuras de datos diferentes para los mismos datos. O construye e indexa en esa matriz :) Pero entonces es mejor usar una base de datos que ya lo tenga implementado.
NSSet
y NSArray
, mi respuesta es precisa y completa. Sí, puede construir otras estructuras de datos, pero solo estoy comparando estos dos.
NSArray
y alguna funcionalidad de NSSet
, la respuesta correcta no es "utilizar NSArray
y sacrificar el rendimiento". La respuesta es combinar ambos o utilizar una estructura de datos diferente.
Una matriz se utiliza para acceder a elementos por su índice. Cualquier elemento se puede insertar en la matriz varias veces. Las matrices mantienen el orden de sus elementos.
Un conjunto se usa básicamente solo para verificar si el artículo está en la colección o no. Los artículos no tienen concepto de orden ni indexación. No puede tener un artículo en un conjunto dos veces.
Si una matriz quiere verificar si contiene un elemento, tiene que verificar todos sus elementos. Los conjuntos están diseñados para utilizar algoritmos más rápidos.
Puedes imaginar un conjunto como un diccionario sin valores.
Tenga en cuenta que la matriz y el conjunto no son las únicas estructuras de datos. Hay otros, por ejemplo, Cola, Pila, Montón, Montón de Fibonacci. Recomendaría leer un libro sobre algoritmos y estructuras de datos.
Consulte wikipedia para obtener más información.
contains
operación es O(n)
. El número de comparaciones cuando no está en la matriz es n
. El número medio de comparaciones cuando el objeto está en la matriz es n/2
. Incluso si se encuentra el objeto, el rendimiento es terrible.
NSArray
s tienen otras ventajas de velocidad sobre NSSet
s. Como siempre, es una compensación.
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);
la matriz
2015-12-04 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)
el conjunto
2015-12-04 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}
Las principales diferencias ya se han dado en otras respuestas.
Solo me gustaría señalar que debido a la forma en que se implementan los conjuntos y diccionarios (es decir, usando hashes), uno debe tener cuidado de no usar objetos mutables para las claves.
Si una clave está mutada, el hash (probablemente) también cambiará, apuntando a un índice / depósito diferente en la tabla hash. El valor original no se eliminará y, de hecho, se tendrá en cuenta al enumerar o preguntar a la estructura su tamaño / recuento.
Esto puede provocar algunos errores realmente difíciles de localizar.
Aquí puede encontrar una comparación bastante completa de las estructuras de datos NSArray
y NSSet
.
Breves conclusiones:
Sí, NSArray es más rápido que NSSet para simplemente mantener e iterar. Tan poco como un 50% más rápido para construir y hasta un 500% más rápido para iterar. Lección: si solo necesita iterar contenidos, no use un NSSet.
Por supuesto, si necesita probar la inclusión, trabaje duro para evitar NSArray. Incluso si necesita pruebas de iteración e inclusión, probablemente debería elegir un NSSet. Si necesita mantener su colección ordenada y también probar su inclusión, entonces debería considerar mantener dos colecciones (una NSArray y una NSSet), cada una con los mismos objetos.
NSDictionary es más lento de construir que NSMapTable, ya que necesita copiar los datos clave. Lo compensa siendo más rápido de buscar. Por supuesto, los dos tienen capacidades diferentes, por lo que la mayoría de las veces, esta determinación debe basarse en otros factores.
Por lo general, usaría un Conjunto cuando la velocidad de acceso es esencial y el orden no importa , o está determinado por otros medios (a través de un predicado o descriptor de clasificación). Core Data, por ejemplo, usa conjuntos cuando se accede a los objetos administrados a través de una relación a muchos
Solo para agregar un poco, uso el conjunto a veces solo para eliminar duplicados de la matriz como: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values