You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
메소드 디스패치: 메소드를 실행할 때 어떤 명령어을 실행해야 하는지 결정하도록 돕는 메커니즘
how a program selects which instructions to execute when invoking a method
글 시작전 알아야 할 것
Static Dispatch : 값 타입(value types) 과 참조 타입(reference types) 모두 지원한다. Dynamic Dispatch : 반면에, 동적디스패치는 참조 타입(reference types)만 지원한다.
이러한 이유는 동적디스패치를 위해서는 상속이 필요한데 값 타입은 상속을 지원하지 않기 때문이다.
크게 보면 , Dispatch 기술은 2가지 타입(Static and Dynamic)이 아닌 4가지 타입으로 나뉜다.
Inline (Fastest)
Static Dispatch
Virtual Dispatch
Dynamic Dispatch (Slowest)
이 중에 어떤 기술을 이용할 지는 컴파일러에 달려있다.
가장 빠른 Inline으로 올라가거나 가장 느린 Dynamic으로 내려오는 등 필요에 따라 결정한다.
Objective-C , Swift
Objective-C
디폴트로 Dynamic Dispatch를 지원한다.
장점
다형성의 형태로 프로그래머에게 상당한 유연성을 제공한다.
이미 존재하는 메소드 등을 서브 클래싱, 재정의 할 수 있기 때문임.
단점
런타임에 필요한 오버헤드가 많아지므로, 비용(Cost)이 많이 든다.
Swift
Dynamic Dispatch를 위해서 우리는 상속을 사용한다.
기본 클래스(base class)를 서브 클래싱하고 기본 클래스에 존재하는 메소드를 재정의(override)한다.
또한, 우리는 dynamic 키워드를 사용하고 @objc 키워드를 prefix하여 Objective-C 런타임에 메소드를 노출시키기도 한다.
Static Dispatch를 위해서 우리는 final, static 키워드를 통해 클래스의 경우 추가적인 상속이나 재정의가 불가능하도록 만든다.
Static vs. Dynamic
Dynamic
런타임 오버헤드의 비용을 증가시켜 언어 표현력(language expressivity)을 향상시킨다.
즉, 메소드를 호출할 때마다, 컴파일러가 특정 메서드의 구현을 확인하기 위해 ,
witness table (가상 테이블 또는 다른 언어의 디스패치 테이블) 이라고 부르는 내부를 조사해야 한다,
컴파일러는 수퍼클래스의 구현을 참조하는지 아니면 하위 클래스의 구현을 참조하는지 판별할 필요가 있다.
그런데, 메모리에 모든 오브젝트는 런타임에 올라가게 되므로 컴파일러는 이러한 과정을 런타임에 해야할 수 밖에 없다.
Static
반면 정적 디스패치는 이렇지 않아도 된다.
컴파일러는 컴파일 타임에 어떤 메소드 구현이 호출되어야할지 알고있다.
그러므로 컴파일러는 여러 최적화 기법을 적용할 수 있고 혹은 코드를 Inline으로 변환(convert)할 수도 있다.
따라서 전체적인 프로그램의 속도를 상당히 빠르게 향상시킬 수 있다.
위의 내용 직관적 정리
Static Dispatch (or Direct Dispatch)
컴파일러가 컴파일타임에 명령어가 어디 있는지 결정이 되어 찾을 수 있으므로, 동적 디스패치와 비교할 때 훨씬 빠르다.
따라서, 함수가 호출 되면 , 컴파일러는 함수의 메모리 주소로 직접 점프하여 작업을 수행한다.
인라인과 같은 특정 컴파일러 최적화와 큰 성능 향상이 될 수 있다.
Dynamic Dispatch
앞에서 설명한 것처럼 이러한 유형의 디스패치에서는 구현이 컴파일 시간 대신 런타임에 선택되어 오버헤드가 추가된다.
그렇다면, 비용이 많이 드는 Dynamic Dispatch 왜 사용할까? ❗️
OOP의 특징인 유연성 (Flexibility) 때문이다.
대부분의 OOP 언어는 다형성(객체 지향 3대 원칙)이라는 특징때문에 Dynamic Dispatch를 지원한다.
Dynamic Dispatch 2가지 타입
Table Dispatch
이 디스패치 기법은 테이블을 사용한다.
여기서 테이블이란 함수 포인터로 이루어진 배열을 의미하며 Witness Table (혹은 Virtual Table)이라고 불린다.
특정 메소드의 구현을 찾는(Look up) 용도로 사용
Witness Table이 어떻게 작동하는가?
모든 서브클래스는 각자의 테이블을 갖고있다.
이 테이블은 서브클래스가 재정의한 모든 메소드에 대해 다른 함수포인터를 갖고있다.
서브클래스가 새로운 메소드를 추가하면 해당 메소드에 대한 함수포인터가 배열 끝에 추가된다.
컴파일러가 런타임에 이 테이블을 사용하여 어떤 메소드를 호출할지 결정한다.
정적 디스패치와 달리 컴파일러가 먼저 테이블로부터 메모리 주소를 읽고(read)
해당 위치로 이동(jump)해야 하므로 두번의 연산이 요구된다.
이것이 정적 디스패치보다 느린 이유다. (메시지 디스패치보다는 여전히 빠르다)
Message Dispatch
이 동적 디스패치 기법은 가장 동적이라고 할 수 있다.
사실 이 기법은 최적화 측면을 제외하면 매우 좋아서
Cocoa 프레임워크에서도 KVO, 코어데이터와 같은 곳에서 자주 사용된다.
이 방법은 런타임에 메소드의 기능(functionality)를 바꾸는 Method Swizzling을 가능하게 한다.
메모리에서 어떤 메커니즘으로 함수를 호출 하는지 알아보자
메소드 디스패치란?
글 시작전 알아야 할 것
Static Dispatch
: 값 타입(value types) 과 참조 타입(reference types) 모두 지원한다.Dynamic Dispatch
: 반면에, 동적디스패치는 참조 타입(reference types)만 지원한다.이러한 이유는 동적디스패치를 위해서는 상속이 필요한데 값 타입은 상속을 지원하지 않기 때문이다.
크게 보면 , Dispatch 기술은 2가지 타입(Static and Dynamic)이 아닌 4가지 타입으로 나뉜다.
이 중에 어떤 기술을 이용할 지는 컴파일러에 달려있다.
가장 빠른 Inline으로 올라가거나 가장 느린 Dynamic으로 내려오는 등 필요에 따라 결정한다.
Objective-C , Swift
Objective-C
Swift
Static vs. Dynamic
Dynamic
런타임
에 올라가게 되므로 컴파일러는 이러한 과정을런타임
에 해야할 수 밖에 없다.Static
컴파일 타임
에 어떤 메소드 구현이 호출되어야할지 알고있다.위의 내용 직관적 정리
Static Dispatch (or Direct Dispatch)
Dynamic Dispatch
그렇다면, 비용이 많이 드는 Dynamic Dispatch 왜 사용할까? ❗️
Dynamic Dispatch 2가지 타입
Table Dispatch
Witness Table
(혹은 Virtual Table)이라고 불린다.Witness Table
이 어떻게 작동하는가?Message Dispatch
Method Swizzling
을 가능하게 한다.예제
값타입
프로토콜
클래스 (참조타입)
참고자료
Static vs Dynamic Dispatch in Swift: A decisive choice
Method Dispatch in Swift 번역본
The text was updated successfully, but these errors were encountered: