Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 애니메이션
- 리펙터링
- UICollectionView
- uiscrollview
- Observable
- Human interface guide
- 리팩토링
- ribs
- Xcode
- HIG
- UITextView
- swiftUI
- ios
- uitableview
- clean architecture
- MVVM
- collectionview
- RxCocoa
- map
- 클린 코드
- Refactoring
- 리펙토링
- tableView
- Protocol
- 스위프트
- swift documentation
- Clean Code
- SWIFT
- rxswift
- combine
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] Static Dispatch, Dynamic Dispatch 성능 최적화 방법, Witness Table, (final, private을 사용하는 이유) 본문
iOS 기본 (swift)
[iOS - swift] Static Dispatch, Dynamic Dispatch 성능 최적화 방법, Witness Table, (final, private을 사용하는 이유)
jake-kim 2021. 12. 24. 01:39final class vs class
final class A {
...
}
class B {
...
}
- class A와 class B의 차이점
- A는 서브클래싱이 불가능
- A는 성능적으로 더욱 높은 장점 -> 성능이 좋은 이유?
- 성능이 좋은 이유 - static dispatch 사용 (아래에서 이어서 개념 설명)
Static Dispatch (Direct Call)
- 변수를 타입에 맞춰서 메소드와 프로퍼티를 참조
- 참조될 요소를 컴파일 타임에 결정
- 상속 가능성이 없다는 keyword를 코드에 표출하면 컴파일러는 Static Dispatch를 사용
Dynamic Dispatch (Indirect Call)
- override, subclass와 같은 변수의 실제 타입의 맞춰서 메소드와 프로퍼티를 호출
- 대표적으로 객체지향 프로그래밍에서 `다형성`에서 Dynamic Dispatch로 접근
- 런타임에 참조할 요소를 O(1)의 시간 복잡도를 가지고 찾는 과정이 존재
성능 최적화를 위해 Static Dispatch를 사용
- override가 필요없는 요소들에는 final 키워드 사용
- 컴파일러는 Static Dispatch로 접근
- private 키워드를 붙여서 선언할 것
- private을 가진 해당 요소는 한 블럭 내에서만 참조되는 것이 보장되고 한 블럭내에 오버라이드가 없는 경우 컴파일러가 이것을 Static Dispatch로 접근
- class보다는 Struct와 enum을 사용
- 서브클래싱이 불가능한 Value Type을 사용하여 Static Dispatch가 이루어지도록 설계
- Reference Type은 오버라이딩이 되지 않는다는 명시적인 키워드를 사용하면(final, private) Static Dispatch지만 나머지는 Dynamic Dispatch를 사용
Protocol은 Dynamic Dispatch를 사용
- Protocol은 구현체를 제공하지 않으므로, 런타임 시에 구현체를 참조하기 위해서 Dynamic Dispatch를 사용
Extension에서의 Dispatch
- Value Type에서의 extension을 사용하면, 상속 가능성이 없기 때문에 Static Dispatch 수행
struct SomeStruct { func someFunction() { ... } } extension SomeStruct { func someAnotherFunction() { ... } }
- Class Type에서의 extension 사용
- extension은 본래 메소드 오버라이딩이 불가능하므로 Static Dispatch 수행
struct SomeClass { func someFunction() { ... } } extension SomeStruct { func someFunction() { ... } // 컴파일 에러! (오버라이딩 불가) }
- extension은 본래 메소드 오버라이딩이 불가능하므로 Static Dispatch 수행
- Protocol에서의 extension 사용
- 기본 지식 - Witness Table이란?
- 프로토콜을 통해 호출하는 메소드는 프로토콜을 채택한 타입들이 실제로 구현한 메소드이므로, 프로토콜 타입의 참조로만 구현체의 내용을 사용할 때 사용되는 프로토콜이 보유한 정보를 `Witness Table`이라 명칭
- Default Implementation (본체에 선언된 멤버 구현): 서브 클래스들이 메소드들을 구현하고 있음이 보장되므로, Witness table을 이용한 Dyanamic Dispatch 수행
protocol SomeProtocol { func someFunction() } extension SomeProtocol { func someFunction() { ... } }
- 본체에 선언되지 않았으므로, 본체가 보유한 Witness Table을 사용하지 못하므로 Static Dispatch 수행
protocol SomeProtocol { func someFunction() } extension SomeProtocol { func someAnotherFunction() { ... } }
- 기본 지식 - Witness Table이란?
* 참고
- WWDC 2016 (Withness Table 내용): https://developer.apple.com/videos/play/wwdc2016/416/
- Increasing performance by reducing dynamic dispatch: https://developer.apple.com/swift/blog/?id=27
'iOS 기본 (swift)' 카테고리의 다른 글
Comments