배열, 부분열 (Array), (Arrayslice)

고양이발냄새·2023년 8월 8일
0

Swift 의 배열은 내부적으로 연속된 공간을 할당받아서 값을 저장한다. 이러한 메모리 레이아웃은 C의 그것과 유사하며, 실제 Swift의 배열은 C의 배열과 유사한 성능을 낸다. 또한 배열은 Reference Type이 아닌 Value Type이다.

하지만 실제로 배열은 너무나 자주 쓰이는 타입이고, 이곳에서 저곳으로 전달되거나 이 변수, 저 변수에 대입되기도 하는데, 이 때마다 값의 복사가 일어나는 것은 지나친 리소스 낭비이기 때문에 내부적으로 copy-on-write전략에 의해서 단순히 참조만 전달될 때에는 마치 참조 시멘틱처럼 참조만 전달되다가 참조 중 어느 한 곳에서 변경이 일어나면 그 시점에 실제 배열의 사본이 만들어지는 구조를 택한다.

  1. 원본 배열 전체의 스토리지를 참조만 한다. 어레이 슬라이스는 참조가 일어나는 그 순간의 값을 snapShot처럼 가지고 있는다. 그래서 나중에 원본이 변한다고 할지라도 arraySlice는 변경되지 않는다. 이는 곳 메모리릭이 일어날수도 있다는 뜻이다

  2. 스토리지자체는 원본 배열이므로, 내부적으로 이중의 startIndex, endIndex를 가져서 필요한 영역만큼을 액세스하게끔 한다. 따라서 startIndex의 값은 항상 0이라는 보장이 없다. 따라서 안전을 위해서는 특정한 정수값보다는 startIndex, endIndex를 쓰도록 하자.

  3. ArraySlice가 살아있는 동안에 Array에 대한 참조는 계속 유지되므로, 이는 오랜시간동안 사용하지 않는 것이 좋다. 특히 라이프 사이클이 긴 클로저 등에서 암묵적으로 ArraySlice를 참조하지 않도록 한다. 이는 원본 배열 자체의 라이프 사이클을 강제로 연장하여 리소스 낭비의 원인이 될 수 있다.

  4. prefix, suffix 와 같은 부분열(Sequence.Subsequcene)을 리턴하는 메소드들도 모두 ArraySlice를 리턴하며, 독립적인 부분열 사본을 리턴하는게 아니다

Range는 contains(_:) 메소드를 갖고 있지만 Sequence는 아니다. 그저 특정값이 해당 범위에 들어가는지만 검사한다.

profile
고양이좋아

0개의 댓글

관련 채용 정보