WWDC 2016 Understanding Swift Performance
위 WWDC 자료를 보고 궁금한 점이 생겨, 알아본 내용입니다.
해당 WWDC의 주 내용은 Struct와 Protocl 그리고 Generic을 사용하여 Protocol 타입을 사용할 경우 Generic과 함께 사용하여 Existential Container를 생성하지 않고, Concrete 한 타입으로 Static Dispatch를 유도하고 Heap 할당을 최소화하여 성능을 개선시킬 수 있는 것이라고 생각합니다.
주로 내용이 Struct + Protocol / Class + Inheritence 위주의 비교였고, Class + Protocol에 대해선 간략하게 나와 있어 이 점에 대해 의문이 들었습니다.
- Class의 경우 Existential Container는 Stack or Heap 중에 어디에 할당이 되는가?
- Class의 경우 inline value buffer의 의미가 있는가? (어짜피 Heap 할당인데,,)
- Class의 경우 Generic을 사용해도 Static Dispatch가 일어나지 않는가?
[메모리 주소를 출력하기 위한 간단한 Helper]
[Protocol 할당 위치 Test]
Class 타입의 경우에는 Stack에 Heap에 대한 메모리 주소만 가지고 있으며, 이는 한 워드(8바이트)로 되어있습니다. (64bit 기준)
따라서 Class 타입의 각 변수들은 8바이트씩 차이가 나는 것을 볼 수 있는데, Protocol 타입의 경우 40바이트를 차지하고 있는 것을 볼 수 있었습니다.
여기서 1번에 대한 해답을 얻을 수 있었습니다. Struct, Class와 관계 없이 Protocol 타입은 Stack에 할당되며, 크기는 40바이트로 고정된 크기를 가지고 있습니다.
여기에서 40바이트의 의미는 3-word의 inline value buffer(24), vwt(8), pwt(8)의 크기를 가진 Existential Container로 사이즈입니다.
[일반 프로토콜과 클래스 전용 프로토콜 비교]
class-only 프로토콜의 경우에는 Protocol 크기가 16바이트로 고정되어 있는 것을 알 수 있습니다.
이는 Class 타입의 경우 Heap에 할당이 되기 때문에, Heap에 대한 reference가 불가피하게 필요하므로 inline value buffer가 필요하지 않아 3-word 만큼 줄어든 크기인 16바이트라고 생각합니다.
이는 class-only 프로토콜의 경우 inline value buffer가 실질적으로 필요하지 않기 때문에 제거한 요소라고 생각할 수 있었습니다.
Generic으로 하여 Concrete한 타입이 지정되기 때문에 Protocol의 Existential Container에 따른 Dynamic dispatch는 막을 수 있지만, 상속, V-Table에 따른 dynamic dispatch는 진행되는 것을 알 수 있었습니다.
'Swift' 카테고리의 다른 글
[Swift] What's New in Swift (5.0/5.1) (1) | 2020.02.29 |
---|---|
[Swift 5.1] Property Wrapper 개념과 사용 예시, 그리고 한계점. (1) | 2020.02.29 |