Swift/개념 & 응용

[Swift] 왜 ContiguousArray는 Array보다 자주 사용되지 않을까?

유정주 2022. 10. 17. 11:05
반응형

서론

(아마 ContiguousArray에 대한 마지막 글)

 

ContiguousArray는 Array보다 효율적입니다.

이는 공식 문서에도 나온 내용이고, 저도 관련해서 포스팅을 썼었죠. (https://jeong9216.tistory.com/468)

하지만 실제 코드를 보면 Array가 훨씬 더 자주 보입니다.

 

문득 궁금했습니다.

ContiguousArray가 더 효율적이면 Array보다 더 자주 사용되어야 하는게 아닌가?

물론, ContiguousArray는 Array보다 덜 대중적이긴 합니다만, Array가 너무 압도적으로 사용이 된단 말이죠?

그래서 혹시 다른 이유는 없는지 찾아보았습니다.

 

참고로 이번 글은 저의 추측 내용도 많기 때문에 참고만 해주시면 감사하겠습니다.

혹시 틀린 내용이 있다면 댓글로 알려주세요.

 

Array도 충분히 효율적이다.

첫 번째 이유는 Array도 충분히 효율적인 자료구조라는 것입니다.

 

ContiguousArray와 Array는 클래스, @objc 타입에서만 차이를 보입니다.

구조체가 멤버인 Array는 ContiguousArray와 비슷한 효율을 보입니다.

이는 공식문서에도 언급된 내용인데요.

If the array’s Element type is a struct or enumeration, Array and ContiguousArray should have similar efficiency.

Swift는 클래스보다 구조체 + 프로토콜을 권장하기 때문에 굳이 ContiguousArray를 적극적으로 사용할 필요가 없습니다.

 

ContiguousArray는 연속적으로 저장되어야 한다.

메모리에 연속적으로 저장되는 것은 ContiguousArray의 장점입니다.

하지만 이 장점이 오히려 단점으로 적용될 수도 있는데요.

바로 배열의 크기가 자주 변경될 때입니다.

 

Array와 ContiguousArray의 capacity는 둘 다 2배에 근사하게 증가합니다.

(count: 현재 배열의 원소 개수, capacity: 현재 배열에 할당 가능한 원소 개수)

10000개의 원소를 배열에 하나씩 append 했을 때의 capacity 변화입니다.

2배에 근사한 수치로 더 큰 메모리 공간에 복사되는 것을 볼 수 있습니다.

2배씩 증가하는 이유는 메모리 복사 과정에서 발생하는 연산 오버헤드를 줄이기 위해서인데요.

이건 Array와 ContiguousArray 공통된 연산입니다.

 

하지만 ContiguousArray에는 하나 더 제한이 있습니다.

바로 "메모리에 연속적으로" 저장되어야 한다는 것입니다.

즉, 연속적으로 저장할 수 없으면 더 큰 메모리 공간에 복사가 되어야 합니다.

따라서 배열의 크기가 자주 변경이 되면 오히려 배열보다 비효율적일 수 있습니다.

 

이를 바탕으로 구글의 여러 질문, 포스팅들을 보면 ContiguousArray의 결과가 제각각인 이유도 이해가 되었습니다.

개발에서는 일정한 성능이 보장되는 것이 중요한데 ContiguousArray는 예상치 못한 순간에 O(n)으로 동작하게 됩니다.

 

그럼 ContiguousArray는 언제 써야할까?

배열 크기가 고정된 상황에서 ContiguousArray를 사용하면 효율적입니다.

추가적인 메모리 복사 오버헤드를 걱정하지 않고 Array보다 빠른 배열 순회가 가능합니다.

 

Swift 내부 코드에서도 ContiguousArray를 적절히 활용하고 있습니다.

대표적인 예시는 Sequence입니다.

Sequence의 map, filter, suffix, prefix 등에서 ContiguousArray로 로직을 수행하고 마지막에 Array로 변환해서 반환합니다.

저희가 매우매우 사랑하는 sorted 함수로 ContiguousArray를 사용 중이에요.

 

이렇게 배열 크기가 고정된 상황에서 배열 순회를 빠르게 하고 싶을 때

ContiguousArray를 사용하면 효율적입니다.


아직은 초보 개발자입니다.

더 효율적인 코드 훈수 환영합니다!

공감 댓글 부탁드립니다.

 

 

반응형