GitHub - apple/swift: The Swift Programming Language
The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.
github.com
final 키워드에 관해 공부하다가 알게된 자료. Optimization Tips 라니.. 노다지라는 것이 아주 잘 느껴지는 제목이다.
더이상 상속될 필요가 없는 클래스의 경우 final을 붙일 수 있다는 건 알고 있었지만 그것이 보편적으로 요구되는 사항이었다는 것은 처음 알게 되었다. 그리고 왜 붙여야하는지도 몰랐기에 제대로 정리하려고 한다. (상속을 안하는 거면 안하는 거지 왜 키워드까지 붙여가며 표시하지..? 이런 생각이었음)
위의 글에서는 동적 디스패치를 줄이기 위한 팁 중 하나의 방법으로 final을 사용할 것을 추천하고 있다.
스위프트는 옵젝씨처럼 매우 동적인 언어인데, 한편으로는 옵젝씨와 달리 프로그래머에게 동적요소를 제거하거나 줄여서 런타임 퍼포먼스를 향상시키는 능력을 제공하고 있다고 함.
아마 동적인 요소가 늘어날수록 런타임 퍼포먼스는 줄어드는 그런 반비례적인 구조인가봄?
아무래도 동적요소가 많아지면 유연성이 늘어나고 이게 성능에는 안 좋은 영향을 미치니까..?
추측은 안 좋은 습관이므로 검색을 해보고 정확한 정보를 찾아보기로 함
Method Dispatch is how a program selects which instructions to execute when invoking a method.
Method Dispatch = 프로그램이 메서드를 호출할 때 실행할 명령을 선택하는 것
뭘 선택하는가? 아래의 예시를 보겠음
class Test {
func printTest() {
print("test")
}
}
class TestA: Test {
override func printTest() {
print("testA")
}
}
class TestB: Test {
override func printTest() {
print("testB")
}
}
let tests = [Test(), TestA(), TestB()]
for test in tests {
test.printTest()
}
참고: https://jeonyeohun.tistory.com/343
[Swift] Method Dispatch 발표자료
Method Dispatch 시리즈의 발표자료입니다! 글로 읽으실 분들은 아래 포스트를 읽으시면 되어요! [Swift] Method Dispatch (1): Static Dispatch vs. Dynamic Dispatch Method Dispatch 글을 시작하기 전에, Method Dispatch가 무
jeonyeohun.tistory.com
위의 클래스를 보면 Test, TestA, TestB의 세 개의 클래스에 모두 printTest 메서드가 있음.
당연함. Test라는 클래스를 TestA, TestB가 상속 받고 있고 있고, override하고 있기 때문
여기서 아래에 test.printTest() 메서드를 컴파일러가 확인했을 때 위에 작성했던 3가지의 정의 중 어떤 것을 선택할지 결정하는 것을 의미하는 것! 이다.
Dispatch의 종류는 크게 두가지로, Static(컴파일 타임에 결정) / Dynamic(런타임에 결정)이 있다.
Static Dispatch는 Enum, Struct 멤버 메서드, static 타입 메서드 등 값타입에 적용되고
Dynamic Dispatch는 Class 멤버 메서드, class 타입 메서드 등 참조타입에 적용된다.
참고로 위의 예시에서는 컴파일러가 어떤 메서드를 선택해야하는지 모르기 때문에 런타임에 결정하는 동적 디스패치를 적용한다.
우리가 눈여겨 볼 부분은 Dynamic Dispatch이므로, 런타임에 결정한다는 것이 어떤 방식으로 동작하는지 알아볼 필요가 있음.
여기서 위에서 언급했던 Optimization Tips의 설명과 내용이 이어진다.
In Swift, dynamic dispatch defaults to indirect invocation through a vtable [1]. If one attaches the dynamic keyword to the declaration, Swift will emit calls via Objective-C message send instead. In both cases this is slower than a direct function call because it prevents many compiler optimizations [2] in addition to the overhead of performing the indirect call itself. In performance critical code, one often will want to restrict this dynamic behavior.
Dynamic Dispatch(동적 디스패치)는 vtable을 통한 간접적인 호출을 기본으로 한다. 라고 되어 있다.
첫줄부터 무슨 말인지 모르겠다.
vtable = 가상 메서드 테이블. 동적 디스패치를 지원하기 위해 프로그래밍 언어에서 사용되는 메커니즘
virtual function/method (가상 함수/메서드) = 상속하는 클래스 내에서 구현되는 시그니처 함수. 오버라이딩 될 수 있는 함수 또는 메서드
클래스가 가상함수를 정의할 때마다 컴파일러는 vtable에 해당 함수의 포인터를 추가함.
vtable은 이런 함수들의 배열을 의미하는 것임.
결국 vtable을 거치는 과정이 한 번은 추가되니, 성능측면에서 안 좋을 수 있다는 의미다.
다시 돌고 돌아 final을 사용하는 이유는?
간접 호출이 기본인 class 키워드 앞에 final을 붙임으로써, 컴파일러에게 이건 상속 안되니까 그냥 바로 호출해~ 하고 알려주는 것이 가능한 거임!!
그래서 컴파일 타임에 메서드를 결정할 수 있어(= Static Dispatch 가능) 성능향상에 도움이 되기 때문에 final을 붙여주는 것이다.
'Swift' 카테고리의 다른 글
[Swift] sync, async, serial, concurrent (0) | 2023.01.17 |
---|---|
[Swift] method swizzling (0) | 2023.01.11 |
[Swift] Safe Index (0) | 2023.01.07 |
[Swift] dynamic var, @objc, @NSManaged (0) | 2023.01.07 |
#0. 목적 (0) | 2020.04.14 |