NSArray를 통해 NSSet을 사용하는 것이 언제 더 낫습니까?


답변:


173

컬렉션의 항목 순서가 중요하지 않은 경우 집합은 컬렉션에서 항목을 찾는 데 더 나은 성능을 제공합니다.

그 이유는 집합이 항목 (사전과 같은)을 찾기 위해 해시 값을 사용하는 반면 배열은 특정 객체를 찾기 위해 전체 내용을 반복해야하기 때문입니다.


9
log (1) 대 log (n)
rohan-patel 2014-06-11

25
@ 로한-파텔 수정은 O (N) 대 O (1)이다
만수 루슬란

1
주문한 경우 : 이진 검색이 적용 가능하므로 O (1) 대 O (logn). 순서가없는 경우 O (1) 대 O (n)
baskInEminence

180

Apple 문서 의 이미지 는이를 매우 잘 설명합니다.

Objective-C 컬렉션

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]

SetA는 없다 구별 (중복 없음) 정렬되지 않은 요소 목록

[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]

2
귀하의 예에서는 배열과 집합에 기본 요소를 추가하고 있습니다. 둘 다 개체 만 포함 할 수 있기 때문에 불가능합니다.
FreeAsInBeer 2012-06-12

10
@Zaheer를 수정 해 주셔서 감사하지만 실제로는 유효하지 않았습니다. 프리미티브를 추가하지 않았습니다. 나는 리터럴을 추가하고 있었다.
James Webster

위대한 설명 : +1 :
캐런

1
당신의 설명을 사랑하십시오! +1
반란

66

이에 대한 가장 좋은 대답은 Apple의 자체 문서 입니다.

여기에 이미지 설명 입력

주요 차이점은 NSArray정렬 된 컬렉션과 NSSet정렬되지 않은 컬렉션에 대한 것입니다.

거기 여러 기사와 같은 둘 사이의 속도 차이에 대한 그 이야기가 있습니다 이 하나 . 순서가 지정되지 않은 컬렉션을 반복하는 경우 NSSet좋습니다. 그러나 대부분의 경우, 당신은 오직 한 사람 만이 할 NSArray수있는 일을해야하기 때문에 그러한 능력을 위해 속도를 희생해야합니다.

NSSet

  • 주로 비교를 통해 항목에 액세스
  • 정렬되지 않음
  • 중복 허용 안함

NSArray

  • 인덱스로 항목에 액세스 할 수 있습니다.
  • 주문
  • 중복 허용

그게 전부입니다! 도움이되는지 알려주세요.


NSSet인덱싱을 위해 항상 희생 할 필요는 없습니다 . 동일한 데이터에 대해 두 개의 서로 다른 데이터 구조를 사용하는 것이 일반적입니다. 또는 해당 배열을 구축하고 인덱싱합니다. :)하지만 이미 구현 된 DB를 사용하는 것이 좋습니다.
Sulthan

"해당 배열에 색인을 작성하십시오". NSSet에 인덱스를 만들 수 없습니다. 사용할 수있는 다양한 기술이 있습니다. 그리고 메모리와 처리 능력을 모두 희생해야한다면 잘못하고있는 것입니다.
Sulthan

질문이 NSSetNSArray에 관한 것이므로 제 답변은 정확하고 완전합니다. 예, 다른 데이터 구조를 구축 할 수 있지만 저는이 두 가지를 비교하고 있습니다.
woz

나는 찬성 투표했지만 희생에 대해 말할 때 귀하의 대답이 잘못되었습니다. 당신이에서 일부 기능이 필요한 경우 NSArray와 일부 functioanlity을 NSSet, 정답은 "사용하지 NSArray희생 성능". 답은 둘 다 결합하거나 다른 데이터 구조를 사용하는 것입니다.
Sulthan

주된 차이점은 배열이 중복을 가질 수있는 고유 한 객체에 대한 것입니다. 질서 측면은 그 사실에 부차적입니다.
malhal

12

NSOrderedSet은 iOS 5 이상에서 사용할 수 있으므로 데이터 구조에서 중복 객체를 원하는지 여부가 주요 차이점입니다.


9

NSArray :

  1. 정렬 된 데이터 수집
  2. 중복 허용
  3. 컬렉션 형 객체입니다

NSSet :

  1. 정렬되지 않은 데이터 수집
  2. 중복 허용 안함
  3. 또한 컬렉션 유형 객체입니다.

7

배열은 인덱스로 항목에 액세스하는 데 사용됩니다. 모든 항목을 배열에 여러 번 삽입 할 수 있습니다. 배열은 요소의 순서를 관리합니다.

세트는 기본적으로 항목이 컬렉션에 있는지 여부를 확인하는 데만 사용됩니다. 항목에는 순서 또는 인덱싱 개념이 없습니다. 한 세트의 아이템을 두 번 가질 수 없습니다.

배열에 요소가 포함되어 있는지 확인하려면 모든 항목을 확인해야합니다. 세트는 더 빠른 알고리즘을 사용하도록 설계되었습니다.

값이없는 사전과 같은 집합을 상상할 수 있습니다.

배열과 집합이 유일한 데이터 구조는 아닙니다. 큐, 스택, 힙, 피보나치의 힙과 같은 다른 것이 있습니다. 알고리즘과 데이터 구조에 대한 책을 읽는 것이 좋습니다.

자세한 내용은 wikipedia 를 참조하십시오.


실제로 배열은 항목이 발견 될 때까지만 확인하면됩니다. 항목이 배열에있는 경우 모든 항목을 확인해야하는 경우는 거의 없습니다.
FreeAsInBeer 2012-06-12

예, "항목이 배열에있는 경우"라고 말합니다. 이것을 예상하면 거기에 있는지 여부를 확인할 필요가 없습니다. 작업의 복잡성 containsO(n). 배열에 없을 때 비교 횟수는 n입니다. 객체가 배열에있을 때 평균 비교 횟수는 n/2입니다. 물체가 발견 되더라도 성능이 끔찍합니다.
Sulthan

성능은 큰 어레이에서만 끔찍합니다. 어레이가 상당히 커질 수 있다는 것을 알고 있다면 어레이 어레이 사용과 같이 어레이 성능을 향상시킬 수있는 방법이 있습니다.
FreeAsInBeer

동등 연산이 비싸면 3 개 항목이있는 배열에서도 차이를 볼 수 있습니다. 작업을 많이 반복하면 큰 배열과 동일한 동작이 발생할 수 있습니다 (예 : 'for'주기에서 작업 사용). 상각 된 복잡성에 대해 들어 보셨습니까? 복잡성은 여전히 ​​선형 적이며 성능은 세트에 비해 끔찍합니다 (일반적으로 일정한 복잡성).
Sulthan

분명히 차이가있을 것입니다. 저는 big o 표기법이 지수 적이라고 말하고 있습니다. 작은 배열을 사용하면 차이가 미미합니다. 또한 NSArrays는 s에 비해 다른 속도 이점이 NSSet있습니다. 항상 그렇듯이 이것은 절충안입니다.
FreeAsInBeer 2012-06-12

5
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)}


4

주요 차이점은 이미 다른 답변에서 제공되었습니다.

집합과 사전이 구현되는 방식 (즉, 해시 사용) 때문에 키에 대해 변경 가능한 객체를 사용하지 않도록주의해야합니다.

키가 변경되면 해시도 (아마도) 변경되어 해시 테이블의 다른 인덱스 / 버킷을 가리 킵니다. 원래 값은 삭제되지 않으며 구조를 열거하거나 크기 / 개수를 요청할 때 실제로 고려됩니다.

이로 인해 버그를 찾기가 매우 어려울 수 있습니다.


3

여기 에서 NSArrayNSSet데이터 구조에 대한 꽤 철저한 비교를 찾을 수 있습니다 .

짧은 결론 :

예, NSArray는 단순히 유지하고 반복하기 때문에 NSSet보다 빠릅니다. 구성 속도가 50 %, 반복 속도가 500 % 빠릅니다. 교훈 : 내용 만 반복해야한다면 NSSet을 사용하지 마십시오.

물론 포함 여부를 테스트해야하는 경우 NSArray를 피하기 위해 열심히 노력하십시오. 반복 및 포함 테스트가 모두 필요하더라도 NSSet을 선택해야합니다. 컬렉션을 순서대로 유지하고 포함 여부를 테스트해야하는 경우 각각 동일한 개체를 포함하는 두 개의 컬렉션 (NSArray 및 NSSet)을 유지하는 것을 고려해야합니다.

NSDictionary는 키 데이터를 복사해야하기 때문에 NSMapTable보다 생성 속도가 느립니다. 검색 속도가 빨라서이를 보완합니다. 물론이 둘은 서로 다른 기능을 가지고 있으므로 대부분의 경우 다른 요인을 고려하여 결정해야합니다.


이 이론적으로 질문에 대답 할 수 있습니다 동안, 바람직 할 것이다 여기에 대한 대답의 본질적인 부분을 포함하고 참조 할 수 있도록 링크를 제공합니다.
Tunaki

2

일반적으로 액세스 속도가 중요하고 순서가 중요하지 않거나 다른 수단 (술어 또는 정렬 설명자를 통해)에 의해 결정될 때 Set을 사용합니다 . 예를 들어 Core Data는 관리 대상 개체가 대다 관계를 통해 액세스 될 때 집합을 사용합니다.


1

약간을 추가하기 위해 가끔 set을 사용하여 배열에서 중복을 제거합니다.

NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.