SubString이란?
Swift에서 문자열(String)에서 일부만 필요에 의해 분리하여 사용하기 위해 prefix(_ : )와 같은 부분 문자열(Substring)을 뽑아내는 메서드를 사용하게 됩니다.
이때 String에서 분리된 문자열은 String 타입이 아닌 Substring 타입으로 따로 정의가 되어 있는데 우리가 사용할 때 굳이 구분하지 않는 이유는 String과 Substring 모두 StringProtocol을 준수하고 있기 때문입니다. (POP의 장점?!)
그렇다면 String에서 분리한 Substring은 메모리에서 어떻게 관리될까?
다음과 예제를 같이 살펴봅시다
let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
위 코드는 "Hello, world!" 문자열(String)에서 "Hello"만 분리하여 beginning 불변 변수(immutable variable)에 할당했습니다.
물론 beginning 불변 변수의 타입을 확인해보면 SubString 타입임을 알 수 있습니다!
아래 이미지는 위 예제 코드의 메모리 구조를 도식화한 것입니다
처음 문자열 "Hello, world!"가 메모리에 할당되고 나서 부분 문자열 "Hello"를 분리했을 때 다시 "Hello"를 재할당해서 beginning이 가리키고 있는 구조가 아닌 부분 문자열이 "Hello, world!"가 저장되어 있는 메모리의 일부를 재사용하고 있음을 알 수 있습니다.
이렇게 구현하면 성능 최적화에 의해 문자열(String)이나 부분 문자열(Substring)을 수정이 일어나기 전까지는 메모리 복사에 대한 비용을 지불할 필요가 없어 메모리를 효율적으로 사용할 수 있다고 합니다.
마치 Swift의 컬렉션 타입에서 지원되는 CoW와 같은 메커니즘이군요! (CoW가 뭔지 잘 모르시는 분들은 CoW란?을 참고해주세요!)
하지만 위의 예제와 같이 부분 문자열은 장기 저장에 적합하지 않다고 합니다..!
왜 부분 문자열은 장기 저장에 적합하지 않나요?
다시 한번 위의 이미지를 살펴보면
부분 문자열(Substring)을 장기 저장하기 위해서는 필요 없을 수도 있는 문자열(String)도 메모리에 계속 유지하고 있어야 함을 알 수 있습니다. 부분 문자열(Substring)이 문자열(String)의 메모리를 공유하여 재사용하고 있기 때문에!
그렇다면 어떻게 개선할 수 있을까요?
만약 부분 문자열을 장기 저장할 필요성이 있다면 아래 코드와 같이 다시 문자열(String) 인스턴스로 만들어주면 됩니다.
let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
// 장기 저장을 위해 String 인스턴스로 변환
let newString = String(beginning)
이렇게 하면 아래 그림과 같은 메모리 구조가 만들어지겠죠!
이렇게 하면 "Hello" 부분 문자열을 유지하기 위해 추가적으로 쓸데없는 "Hello, world!" 문자열 인스턴스를 메모리에 계속해서 할당해 둘 필요가 없을 겁니다.
메모리에는 필요한 "Hello" 문자열(String) 인스턴스만 유지하면 되겠죠!
'iOS > Swift' 카테고리의 다른 글
[Swift] Subscript 알아보기 :: String에서는 subscript를 사용할 수 없는 이유 (0) | 2023.03.02 |
---|---|
[Swift] AnyObject란? (런타임 시점에 결정된다) (0) | 2023.02.23 |
[Swift] 문자열은 무엇으로 구성되어 있을까? - Extended Grapheme Clusters (0) | 2023.02.18 |
[Swift] Convenience initializer 알아보기 (0) | 2023.02.16 |
[Swift] CoW(Copy on Write)의 동작방식 + 메모리 주소 디버깅 (1) | 2023.02.16 |