티스토리 뷰

안녕하세요 Hani입니다.

이번에는 WWDC16에서 발표된 Understanding Swift Performance에 대하여 알아볼 거예요. ☺️

 

목차는 총 5개로 이루어져 있어요

1. Allocation

2. Reference Counting

3. Method Dispatch

4. Protocol Types

5. Generic Code

 

스위프트에서는 성능을 고려할 때 세 가지를 고민해야 합니다.

 

인스턴스를 생성할 때 스택/힙 중 어느 곳에 Allocation되는지

인스턴스를 전달할 때 Reference Counting 오버헤드가 얼마나 발생하는지

메서드를 호출할 때 Method Dispatch의 방식은 어느 것을 따르는 지

 

 

이번 포스팅에서는 Allocation에 대하여 다뤄보려고 합니다. 🥰

스택에서는 단순히 스택 포인터를 감소/증가시켜서 메모리를 할당/할당해제할 수 있어요.

스택 포인터를 옮기는 시간은 O(1)으로, 짧은 시간에 간단히 가능합니다.

 

 

힙의 경우에는 스택보다 조금 더 복잡합니다.

힙은 인스턴스를 메모리에 할당하기 위해 아직 사용되지 않은 메모리 중에서 충분한 공간의 연속적인 메모리를 찾아야하고, 

메모리에서 할당해제할 때는 해당 메모리를 힙에 다시 집어넣어줘야 합니다.

 

 

스택은 각 스레드마다 고유하게 가지고 있는 메모리 영역이지만

힙은 한 프로세스의 모든 스레드들이 공유하고 있는 영역이기 때문에

복수의 스레드가 동시에 데이터에 접근하여 발생할 수 있는 문제점을 Locking 혹은 Synchronization을 통해 해결해야해요 🥺

 

따라서 힙은 스택보다 비용이 조금 더 드는 자료구조라고 할 수 있습니다.

 

 

이제 메모리를 스택에 할당할 때와 힙에 할당할 때의 차이를 알아봅시당.

구조체로 구성된 Point 타입이 있습니다.

이를 위해 스택에 메모리를 할당하고

 

할당한 메모리를 Point 구조체의 인스턴스로 초기화합니다.

구조체의 인스턴스이기 때문에 두 객체는 서로 다른 객체에요.

 

 

point1과 point2는 각각 다른 인스턴스이기 때문에 한 인스턴스의 값이 바뀌어도 다른 인스턴스에 영향을 주지 않습니다.

 

 

인스턴스를 전부 사용하고 나면 메모리 할당해제가 되죠.

 

 

 

 

이제 Point 구조체를 Point 클래스로 바꿔서 살펴봅시당. 😊

힙에 할당될 메모리의 참조를 위한 메모리를 스택에 할당해줍니다.

 

 

그리고 Point 클래스의 인스턴스를 위한 메모리를 힙에 할당해주고

 

 

할당된 힙 메모리를 Point 인스턴스로 초기화합니다.

 

그런데 할당된 힙 메모리가 4칸인 이유가 point1, point2에 대한 x, y 프로퍼티를 저장하기 위함이 아니었네요.

파란색 부분은 인스턴스를 관리를 위해 추가적으로 할당한 메모리입니다. 👍

 

 

구조체와는 다르게 클래스에서의 point2는 point1을 똑같이 복사하게 새롭게 할당한 것이 아니라

해당 인스턴스의 참조를 복사합니다.

 

 

인스턴스의 참조를 복사한 것이기 때문에 인스턴스의 프로퍼티 값을 바꾸면

해당 인스턴스를 참조하고 있는 다른 변수로 접근했을 때도 바뀐 값을 가져오게 됩니다.

 

 

사용이 끝나면 할당받은 힙 메모리를 도로 가져다 놓습니다.

 

스택 포인터도 증가시켜 스택 메모리도 할당해제합니다.

 

 

 

다른 예시를 한 번 더 볼게요.  

Enum을 전달인자로 받아 이미지를 리턴해주는 함수가 있네욥.

 

 

UI요소는 빠르게 화면에 띄워져야 하기 때문에 함수가 여러 번 실행될 것을 대비해서

매 번 이미지를 만드는 것 보다 캐시를 통해 가져오는 게 더 낫겠죠?

 

그래서 String을 Key로 하는 딕셔너리를 만들어서 이미지를 가져오는 것이 제안됩니다.

 

 

 

하지만 이 방법에는 문제점이 있어요. 🥺

문자열을 Key로 넣다보니 캐시 히트가 일어나든 일어나지 않든 문자열의 힙 할당이 일어납니다..!

 

그래서 할당에 대한 비용을 줄이기 위해 내부 타입이 Enum으로 구성된 구조체를 Key로 하는 딕셔너리를 만들어줍니다.

 

이 코드에서는 Key를 위해 문자열을 할당하는 과정이 없기 때문에

기존보다 빠르게 이미지를 가져올 수 있습니다.

 

 

 

 

다음 편에서 만나요 ☺️


References

https://developer.apple.com/videos/play/wwdc2016/416/

 

 

 

댓글