파이썬에 존재하는 copy 모듈을 import하면 copy() 함수와 deepcopy() 함수가 존재한다.
copy()
함수는 얕은 복사를 하고 ex. b = copy.copy(a)
deepcopy()
함수는 깊은 복사를 한다 ex. b = deepcopy(a)
그리고 얕은 복사는 =
를 사용해서도 사용이 가능하고 ex. b = a
깊은 복사는 slicing
을 통해 사용이 가능하다 ex. b = a[:]
DeepCopy(깊은 복사), shallow Copy(얕은 복사)
얕은 복사인 경우 a와 b가 동일한 id 즉, 동일한 주소를 가리킨다.
그리고 깊은 복사인 경우 a와 b가 다른 id(주소)를 가리키므로,
a와 b는 독립적인 객체인것이다.
래퍼런스 카운트(Reference Count)
래퍼런스 카운트는 참조 횟수 계산 방식이라고 한다.
참조카운팅(reference counting) 방식
- 래퍼런스 카운트는 3이다. 이는 참조 카운트라고도 하는데 객체를 참조하는 변수의 수를 뜻한다.
- del 키워드를 사용해 a, c의 변수를 지웠다. 그럼 참조 카운트는 1이 되고 b만 남는다.
- del 키워드를 사용해 마지막 b의 변수를 지웠다. 이 때 메모리에 있는 객체에 대한 참조 카운트가 0이면 객체가 바로 메모리에서 해지된다.
+) 가비지 컬렉션
위의 경우 참조 카운트가 0인 경우 메모리에서 객체가 바로 해지되는 데 반해,
가비지 컬렉션인 경우 쓰레기 수집 알고리즘이 수행 될 때 해지가 된다.
그리고 쓰레기 수집 알고리즘은 주기를 가지고 수행되기 때문에 객체의 해지 시점은 참조카운팅 방식보다 늦을 수 있다.
또한 쓰레기 수집 알고리즘에 따라 오버헤드가 달라질 수 있다.
+) 깊은 복사의 두 가지 방법의 속도 차이
위에서 말했다시피 깊은 복사에는 두 가지 방법이 존재한다.
(1) deepcopy() 방식
이 방식은 import에 긴 시간이 소요될 수 있다.
deepcopy()
함수는 객체의 모든 속성과 데이터를 복사해온다. 때문에 배열보다는 class 객체나, dictionary 같은 해시값을 복사해올때 이점있고, memo 속성을 넣어 최적화하는데 사용할 수 있다.
(2)slicing 방식
slicing
은 리스트의 요소 갯수 만큼의 시간 복잡도를 가진다.
때문에 copy 모듈보다 시간이 적게 소요될 수 있다.
위의 설명처럼 deepcopy()
함수는 굉장히 느리다. 때문에 객체등을 복사할 때는 복사 메서드를 커스텀으로 만들어서 사용한다고 한다.
참고 문헌
https://thrillfighter.tistory.com/272
https://velog.io/@emplam27