뚝딱뚝딱 모바일

[Swift] Copy On Write (COW)에 대해 알아보자 본문

iOS 지식

[Swift] Copy On Write (COW)에 대해 알아보자

규석 2023. 3. 17. 01:48

안녕하세요!
이번엔 Copy On Write (COW)에 대해 알아보겠습니다.


Copy On Write란?

Copy On Write란 무엇일까요? 직역해 보면 '쓸 때 복사한다' 정도 되겠네요.
이 직역처럼 Copy On Write는 사용할 때 복사하는 것을 말합니다.

Copy On Write는 리소스를 복사할 때, 원본이나 복사본이 수정되지 않은 경우에는 복사본이 원본을 참조하여 공유하고, 수정이 일어났을 때만 새 리소스를 만드는 것을 말합니다.
줄여서 COW라고도 합니다. 음메
 
Swift에서는 이 Copy On Write를 CollectionType (Array, Set, Dictionary)에서 사용하고 있습니다.

var arr1: [Int] = [0, 1, 2, 3, 4, 5]

 
이런 배열이 하나 있다 생각해 봅시다.
이 배열을 새로운 배열로 복사를 합니다.

var arr2 = arr1

Collection Type은 Struct로 이루어진 Value Type이니
메모리에 arr1과 arr2가 각각 있어야 되는 것으로 생각이 됩니다. 
그러나...!

짜잔, 절대란 없더군요

엥? 분명 우리가 아는 Struct는 참조가 아닌 복사가 일어나야 되는데? 라고 혼동이 오실 수 있다 생각합니다. 
이는 메모리 절약을 위해 수정되기 전까지는 원본의 주소를 가지고 '복사된 척'하고 있는 거라 생각하시면 좋을 것 같습니다.
(+ Copy On Write를 사용하는 Collection Type에 한한 겁니다. Copy On Write를 사용하지 않는 Struct들은 위와 같이 생성할 시, 처음부터 주소가 다르게 나옵니다.)
 
수정이 이루어지면 본래 우리가 아는 Struct처럼 새로운 메모리 주소를 들고 있습니다. 

arr1[0] = 1
// 원본 또는 복사본, 둘 중 하나라도 수정이 일어난다면
arr2[0] = 1

이렇게 수정을 해주면

!!

이렇게 메모리 주소가 서로 다른 것을 알 수 있습니다.
 
이렇게 Copy On Write를 알아봤는데, 궁금점이 드실 겁니다.

아니 처음부터 복사할 것이지, 왜 이렇게 귀찮게 하냐?

물론, 모든 값을 복사하고 수정한다면, Copy On Write는 왜 있는지 모를 행위이긴 합니다.
그러나 우린 복사한 후에 원본이든 복사본이든 수정하지 않을 때가 있을 거란 말이죠.
이렇게 되면 더 이상 수정하지도 않을 같은 값 두 개를 메모리에 넣어두어야 하기에 메모리는 Copy On Write를 쓸 때보다 훨씬 먹고 있습니다.
 
그렇기에 수정이 이루어질 때 복사를 하고, 그전엔 원본의 메모리 주소를 들고 있어서 불필요한 메모리 차지를 하지 말자!
가 Copy On Write의 장점이자 의의라 보시면 될 것 같습니다.
 
 
 + 여기서 또 궁금점이 드시는 분이 있으실 겁니다.

그럼 처음으로 수정을 진행할 때 복사를 해야 되니 실행 시간이 좀 더 걸리겠네? 

네, 맞습니다.

var arr1: [Int] = [0, 1, 2, 3, 4, 5]
var arr2 = arr1

let clock = ContinuousClock()

let result1 = clock.measure {
    arr2[0] = 1
}

print(result1)

let result2 = clock.measure {
    arr2[0] = 1
}

print(result2)

ContinuousClock 클래스를 활용하여 시간을 측정해 보니

아래는 0.000015208 입니당

차이가 꽤 나는 것을 볼 수 있었습니다. 여러 번 시도해도 처음 수정 작업은 훨씬 오래 걸렸습니다.
 
이렇게 Copy On Write에 대해 정리해 봤습니다. 어려운 개념은 아니지만 CS를 공부할 때, 자주 나오는 개념이라 잘 외워두시면 좋을 것 같습니다.