Я много раз использовал NSSets в своих приложениях, но сам никогда не создавал их.
Я много раз использовал NSSets в своих приложениях, но сам никогда не создавал их.
Ответы:
Когда порядок элементов в коллекции не важен, наборы обеспечивают лучшую производительность для поиска элементов в коллекции.
Причина в том, что набор использует хеш-значения для поиска элементов (например, словарь), в то время как массив должен перебирать все свое содержимое, чтобы найти конкретный объект.
Изображение из документации 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
для неупорядоченной коллекции.
Есть несколько статей, в которых говорится о разнице в скорости между ними, как эта . Если вы перебираете неупорядоченную коллекцию, NSSet
отлично. Однако во многих случаях вам нужно делать то, что только NSArray
может, поэтому вы жертвуете скоростью ради этих способностей.
NSSet
NSArray
Вот и все, что нужно сделать! Сообщите мне, если это поможет.
NSSet
ради индексации. Обычно для одних и тех же данных используются две разные структуры данных. Или вы создаете и индексируете этот массив :) Но тогда лучше использовать БД, в которой он уже реализован.
NSSet
и NSArray
, мой ответ точный и полный. Да, вы можете создавать другие структуры данных, но я просто сравниваю эти две.
NSArray
и некоторая функциональность NSSet
, правильный ответ - не «использовать NSArray
и жертвовать производительностью». Ответ - объединить оба или использовать другую структуру данных.
Массив используется для доступа к элементам по их индексу. Любой элемент можно вставить в массив несколько раз. Массивы сохраняют порядок своих элементов.
Набор используется в основном только для проверки, находится ли элемент в коллекции или нет. Элементы не имеют понятия порядка или индексации. Вы не можете иметь предмет в наборе дважды.
Если массив хочет проверить, содержит ли он элемент, он должен проверить все его элементы. Наборы предназначены для использования более быстрых алгоритмов.
Вы можете представить себе набор как словарь без значений.
Обратите внимание, что массив и набор - не единственные структуры данных. Есть и другие, например, очередь, стек, куча, куча Фибоначчи. Я бы рекомендовал прочитать книгу об алгоритмах и структурах данных.
См. Википедию для получения дополнительной информации.
contains
операции O(n)
. Количество сравнений, когда нет в массиве n
. Среднее количество сравнений, когда объект находится в массиве, составляет n/2
. Даже если объект найден, производительность ужасная.
NSArray
s есть другие преимущества в скорости перед NSSet
s. Как всегда, это компромисс.
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. Если вам нужно упорядочить свою коллекцию, а также проверить ее на включение, вам следует рассмотреть возможность сохранения двух коллекций (NSArray и NSSet), каждая из которых содержит одни и те же объекты.
NSDictionary создается медленнее, чем NSMapTable, поскольку ему необходимо копировать ключевые данные. Это компенсируется более быстрым поиском. Конечно, у них разные возможности, поэтому в большинстве случаев это определение следует делать по другим факторам.
Обычно вы используете Set, когда скорость доступа имеет существенное значение, а порядок не имеет значения или определяется другими способами (через предикат или дескриптор сортировки). Core Data, например, использует наборы, когда доступ к управляемым объектам осуществляется через отношение ко многим.
Просто чтобы добавить немного, я иногда использую set, чтобы удалить дубликаты из массива, например: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values