[iOS] COW 구현해보기

Youngwoo Lee·2022년 4월 29일
0

iOS

목록 보기
46/46
post-thumbnail

들어가며

면접 중 받았던 질문 중 COW(Copy-On-Write) 에 대해서 질문을 받았었다. 물론 개념도 알고 왜 사용되는지 알지만, 바로 대답을 못했어서 아쉬웠다. 오늘 기록해보고 커스텀 타입에서 COW를 구현하는 방법에 대해서 알아보자.

Collection Type 에서의 COW

Copy On Write는 Swift의 성능 향상을 위한 기술 중 하나이다. 구조체의 경우 클래스보다 성능이 여러 면에서 우의를 점하고 있는데, 딱 하나의 단점이 있다. 값 타입이기 때문에 항상 값 복사가 일어나면 메모리 공간 상에서 비효율적이라는 것이다.

그래서 Swift는 Array와 같은 Collection Type에서 Copy-On-Write를 제공한다.

Copy-On-Write 는 값타입임에도 초기에는 참조를 하고, 실제로 값이 변경되었을 때에 값 복사를 해주는 기술이다. 아래의 코드에서 확인해보자

func address(of object: UnsafeRawPointer) -> String{
  let address = Int(bitPattern: object)
  return String(format: "%p", address)
}

var firstArray: [Int] = [1,2,3]
var secondArray: [Int] = firstArray

print(address(of: &firstArray)) //0x10125bd80
print(address(of: &secondArray)) //0x10125bd80

값 복사가 일어나면 당연스럽게 메모리 주소가 달라야겠지만, 아직 값을 변경하지 않았으므로 참조가 일어나고 있어, 메모리 주소가 같은 것을 볼 수 있다.

secondArray = [4,5,6]

print(address(of: &firstArray)) //0x10125bd80
print(address(of: &secondArray)) //0x101105d00

그리고 설명처럼 값을 변경시켰을 때는? 이렇게 메모리 주소가 변경되는 것을 볼 수 있다!

Custom Type에서의 COW

그렇다면 내가 직접 만든 타입에서 COW를 통해 성능향상을 경험하고 싶다면? 어떻게 해야될까?

일단 커스텀 타입을 생성한다.

struct Coordinate {
	var x: Int
    var y: Int
}

다음으로는, 대입연산에 의해 즉각적인 복사가 일어나는 것을 막기위해 참조타입으로 Coordinate을 한번 Wrapping 해줘야 된다.

final class DataWrapper<T> {
    var data: T

    init(data: T) {
      self.data = data
    }
}

dataWrapper에 대한 참조가 Uniquely하지 않으면 새로운 Wrapper를 생성하여 값을 대입해줍니다.

struct CowData<T> {
    private var dataWrapper: DataWrapper<T>

    init(data: T) {
        self.dataWrapper = DataWrapper(data: data)
    }

    var data: T {
        get {
            return self.dataWrapper.data
        }
        set {
            if !isKnownUniquelyReferenced(&self.dataWrapper) {
                self.dataWrapper = DataWrapper(data: newValue)
            } else {
                self.dataWrapper.data = newValue
            }
        }
    }
}

아주 간단합니다. 실제 현업 코드에서 모든 Struct 타입들에 적용할지는 잘 모르겠지만, 만약 값 복사가 많이 발생한다면? 한 번 고려해볼만 사항인 것 같다!

profile
iOS Developer Student

0개의 댓글