반응형
LinkedIn 개발자로 성장하면서 남긴 발자취들을 확인하실 수 있습니다.
Github WWDC Student Challenge 및 Cherish, Tiramisul 등 개발한 앱들의 코드를 확인하실 수 있습니다.
개인 앱 : Cherish 내 마음을 들여다보는 시간, 체리시는 디자이너와 PM과 함께 진행 중인 1인 개발 프로젝트입니다.
10년 후, 20년 후 나는 어떤 스토리 텔러가 되어 있을지 궁금하다. 내가 만약에 아직 조금 더 탐구하고 싶은 게 있고, 궁금한 게 있다면, 그게 설사 지금 당장의 내 인생에 도움이 안 되는 것 같더라도 경험해보자. 그 경험들을 온전히 즐기며 내 것으로 만들고, 내 일에 녹여내고... 그러다보면 그 점들이 모여 나란 사람을 그려내는 선이 될 테니까.

Recent Posts
Recent Comments
Total
관리 메뉴

꿈꾸는리버리

Copy On Write(COW)는 어떤 방식으로 동작하는지 설명하시오. 본문

오뚝이 개발자/swift

Copy On Write(COW)는 어떤 방식으로 동작하는지 설명하시오.

rriver2 2022. 7. 14. 22:32
반응형

이전 블로그에서 class와 struct의 차이에 대해서 알아봤었다.

 


해당 블로그에서 필요한 부분만 발췌..

// FoodClass와 FoodStruct에 인스턴스를 각각 만들고 대입을 해준다.

// class
var food1 = FoodClass(name: "핏자", calorie: 100)
var food_1 = food1
food1.name = "핏자유~"
food1.name  //"핏자유~"
food_1.name //"핏자유~"

// struct
var food2 = FoodStruct(name: "핏자", calorie: 100)
var food_2 = food2
food2.name = "핏자유~"
food2.name  //"핏자유~"
food_2.name //"핏자"

 

class의 경우에는 해당 인스턴스를 복사했을 때 주솟값을 복사하기 때문에,

food1.name을 바꿨을 때 food1과 food_1 모두 변경된 값이 적용되는 반면에,

 

struct의 경우에는 인스턴스의 프로퍼티들의 값을 복사하기 때문에,

food2.name을 바꾸더라도 food_2에 변경된 값이 반영되지 않는다.

 

해당 내용은 다음 그림과 같다.


  생각해봐야 하는 것  

위와 같은 이유로 class에서는 한 인스턴스(food1)의 값이 변경될 시에 다른 인스턴스(food2)에서의 값도 변경되기 때문에 의도치 않은 문제가 발생 할 수도 있다고 했다. 이렇게 발생된 문제는 참조가 많은 경우에 문제의 발생지를 찾기 어렵기 때문에 디버깅이 까다로울 수 있다. 그래서 Immutable한 경우에는 struct을 사용하라고 권장했었다. 

 

struct는 대입시 값을 복사하기 때문에, 인스턴스의 값을 변경한다해도 다른 곳에 영향을 주지 않게 된다. 따라서 위에서 알아본 class에서 발생하는 문제를 해결할 수 있다.

하지만 struct의 덩치가 커지게되면 struct간 대입연산(=)시에 모든 값이 복사되어야 하기 때문에 속도적인 면에서 class에 비해 큰 비용이 발생하게 된다.

또, 만약 struct의 값이 변경되지 않을 때에도 대입연산시 매번 새로운 메모리 공간을 할당해 프로퍼티를 복사하므로 불필요한 메모리 할당이되는 문제가 발생하게 된다.

 

그래서 이 둘을 적절히 짬뽕 시켜서 나온 게 "Copy on write" 이다 !


  Copy On Write  

copy on write를 직역하면 , "write할 때 복사한다"

 

이렇게 이름 붙여진 거 그대로 copy on write는 

let A = B

 

" 대입연산을 했을 시, 실제 원본(B)나 복사본(A)가 수정되기 전까지는 복사가 되지 않고
동일한 값을 참조하다 원본(B)나 복사본(A)가 변경될 시에 복사하는 작업을 수행하는 매커니즘이다. "

 

swift는 기본적으로 struct인 Collection 즉, array, dictionary, set에 해당 copy on write을 지원해준다.

 

 

한번 예시를 통해 알아보자 :)

import Foundation

// 주소를 출력하기 위한 함수
func address(address o: UnsafeRawPointer ) {
    print(String(format: "%p", Int(bitPattern: o)))
}

var array1: [Int] = [0, 1, 2, 3]
var array2 = array1

// 대입만 했을 시에 주소 값은 동일
address(address: array1) //0x600000078de0
address(address: array2) //0x600000078de0

// 만약 array2의 값이 변했을 경우에
array2.append(4)
// array2의 주솟값이 달라짐 !
address(address: array1) //0x600000078de0
address(address: array2) //0x6000000aa100

그래서 대입만하고 변경을 하지 않았을 때, 좀 더 빠르게 접근이 가능하다 :)

다만, 변경이 있을 시에는 첫 복사 때문에 조금 느려지겠지만..

 

 

느낌상 다른 것도 있을 거 같지 않은가..?ㅎㅎ

 

  Copy On Assign  

고것은 바로 Copy On Assign !

swift에서의 Collection과 달리 내가 직접 짠 struct은 Copy On Write가 되지 않는다.

struct Struct2 {
    var number = 1
}

var var1 = Struct2()
var var2 = var1

// 다른 주솟값이 나옴 
withUnsafePointer(to: &var1) {
    print("\($0)") // 0x0000000104a68488)
}
withUnsafePointer(to: &var2) {
    print("\($0)") // 0x0000000104a684a0)
}

이 말은 즉, 대입 연산을 수행할 때 즉시적으로 모든 값이 copy되는 것을 의미한다.

메모리 성능을 위해서라면 개발자가 추가적으로 코드를 작성해야 겠지..?

(구글링을 하니까 직접 코딩해본 사람들이 있던데.. swift 문법이 부족한 나로서는 .. 이해를 다 못했기에.. 후에 포스팅을 추가하고자 한다 !)

 

 


 

이렇게 Copy On Write와 Copy On Assign라는 개체를 복사할 때 내부적으로 발생하는 두 가지 중요한 메커니즘을 알아봤다 !

 

이를 통해서 메모리를 더 좋고 효율적으로 사용할 수 있는 제어 기능을 제공한다 !

 

이런 치밀한 사람들 ! 

반응형

'오뚝이 개발자 > swift' 카테고리의 다른 글

protocol 정복기 ( 1 / 3)  (0) 2022.07.24
Class 안의 Struct와 Struct 안의 Class !  (0) 2022.07.14
Xcode SwiftLint 적용하기  (0) 2022.07.11
assert(_:_:file:line:)  (0) 2022.07.10
struct와 class의 차이를 설명하시오.  (0) 2022.07.06
Comments