본문 바로가기

Swift

[Swift] Understanding Swift Performance - Class와 Protocol

반응형

WWDC 2016 Understanding Swift Performance 

 

Understanding Swift Performance - WWDC 2016 - Videos - Apple Developer

In this advanced session, find out how structs, classes, protocols, and generics are implemented in Swift. Learn about their relative...

developer.apple.com

 

위 WWDC 자료를 보고 궁금한 점이 생겨, 알아본 내용입니다.

 

해당 WWDC의 주 내용은 Struct와 Protocl 그리고 Generic을 사용하여 Protocol 타입을 사용할 경우 Generic과 함께 사용하여 Existential Container를 생성하지 않고, Concrete 한 타입으로 Static Dispatch를 유도하고 Heap 할당을 최소화하여 성능을 개선시킬 수 있는 것이라고 생각합니다.

 

주로 내용이 Struct + Protocol / Class + Inheritence 위주의 비교였고, Class + Protocol에 대해선 간략하게 나와 있어 이 점에 대해 의문이 들었습니다.

 

  1. Class의 경우 Existential Container는 Stack or Heap 중에 어디에 할당이 되는가?
  2. Class의 경우 inline value buffer의 의미가 있는가? (어짜피 Heap 할당인데,,)
  3. 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는 진행되는 것을 알 수 있었습니다.

반응형