WWDC16 Understanding Swift Performance (특강 내용정리 - 2)

JG Ahn·2025년 1월 10일

iOS

목록 보기
19/32
post-thumbnail

3. Method Dispatch

Swift에서 Method Dispatch는 메서드 호출 시 어떤 방식으로 호출할 메서드가 결정되고 실행되는지를 의미한다.
Method Dispatch의 종류에는 Static dispatch, Dynamic dispatch가 있다.

Static Dispatch (정적 디스패치)

  • Static Dispatch는 컴파일 타임에 호출할 메서드가 결정된다. 즉, 호출할 메서드의 구현체가 컴파일 시점에 고정된다는 것을 의미하며 컴파일러가 소스 코드를 분석하여 어떤 메서드가 호출될지 이미 알고 직접 점프하는 코드를 생성한다.

  • Static Dispatch는 inlining을 적용해서 코드 최적화를 수행할 수 있다.

💡inlining : 함수 호출을 제거하고 함수의 본문을 호출하는 코드(함수 구현 코드)로 직접 대체하는 최적화 기법

Dynamic Dispatch (동적 디스패치)

  • Dynamic Dispatch는 컴파일 타임에 어떤 메서드를 호출할지 결정할 수 없다(가시성이 좋지 않다). 어떤 구현체인지 파악이 되지 않기 때문에 런타임에 구현체들을 탐색해서 맞는 구현체로 점프한다. 이러한 특성 때문에 컴파일러를 통한 코드 최적화가 불가능하다.

  • Dynamic Dispatch는 다형성이 적용된 경우 즉, 상속 관계에서 메서드 오버라이딩이 사용될 때 주로 나타난다.

예시)

class Animal {
    func sound() {
        print("Animal sound")
    }
}

class Dog: Animal {
    override func sound() {
        print("Woof!")
    }
}

class Cat: Animal {
    override func sound() {
        print("Meow!")
    }
}

let animals: [Animal] = [Dog(), Cat(), Animal()]

for animal in animals {
    animal.sound()
}

animals 배열의 요소들은 컴파일 타임에 모두 Animal 타입으로 보인다. 하지만 실제로 배열에는 Dog, Cat, Animal의 인스턴스가 들어있다. 따라서 animal.sound() 호출 시 런타임에 실제 객체의 타입에 따라 적절한 메서드를 호출해야 하기 때문에 Dynamic Dispatch가 사용되고 아래의 결과가 출력된다.

Woof!
Meow!
Animal sound
  • Dynamic Dispatch에서는 inlining을 적용할 수 없다.
    inlining은 컴파일 타임에 컴파일러가 함수 호출을 제거하고, 함수의 본문을 호출 위치로 복사하여 대체한다. 하지만 Dynamic Dispatch는 다형성의 특성 때문에 호출 대상이 컴파일 타임에 결정되지 않아서 컴파일러가 inlining을 적용 할 수 없다.

Static Dispatch VS Dynamic Dispatch

- Static Dispatch가 사용되는 경우

  • final 키워드가 붙은 메서드 : 상속을 의도하지 않음을 final 키워드로 명시
  • struct나 enum에 정의된 메서드
  • private 메서드(가시성이 클래스 내로 제한되어 오버라이딩 불가능한 경우)

- Dynamic Dispatch가 사용되는 경우

  • @objc 키워드가 붙은 메서드
  • Objective-C 클래스에서 상속된 메서드
  • dynamic 키워드를 명시적으로 붙인 메서드

0개의 댓글