본문 바로가기

Swift

[Swift] final 왜 쓰는지 아시나요?

 더이상 상속하지 않을 class 일 때, 습관적으로 사용했던 final.. final 은 왜 사용할까?

 

 

'더이상 상속하지 않겠다' 라고 생각이 들 때 습관처럼 썼던 final...

 

https://github.com/apple/swift/blob/main/docs/OptimizationTips.rst#advice-use-final-when-you-know-the-declaration-does-not-need-to-be-overridden

 

실제로 애플 깃허브에서는 final 사용이 성능을 개선시켜준다는 팁이 적혀있다.

 

 

 

 

이유를 설명하기에 앞서 컴파일 타임, 런 타임, Dispatch, vtable 에 대한 설명이 필요하다.

 

 

 

☑️ 컴파일 타임(CompileTime)과 런 타임(RunTime)

프로그램을 생성하기 위해 개발자는 소스코드를 작성하고 컴파일이라는 과정을 통해 기계어 코드로 변환돼 실행 가능한 프로그램이 된다. 이러한 편집 과정을 우리는 컴파일 타임(CompileTime) 이라고 한다.

 

컴파일과정을 마친 프로그램은 사용자에 의해 실행되며 이러한 응용 프로그램이 동작되는 때를 런 타임(RunTime) 이라고 한다.

 

 

 

☑️ Dispatch

Dispatch 는 어떤 메서드를 호출할 것인지를 결정하여, 그것을 실행하는 메커니즘이다. Dispatch 라는 건 내가 호출할 함수를 '컴파일 타임 에 호출하냐', '런 타임 에 호출하냐' 로 나눌 수 있다.

 

Swift 에선 Static Dispatch 과 Dynamic Dispatch 2가지 방식이 있다. 

 

Static Dispatch 는 컴파일 타임에 호출될 함수를 결정하며 런 타임 때 실행한다. 런 타임에 비해 이른 시간인 컴파일 타임에 결정이 나기 때문에 성능상 이점을 가질 수 있다.

 

Dynamic Dispatch 는 런 타임에 호출될 함수를 결정한다. 그래서 Swift 에서는 클래스마다 vTable(Virtual Dispatch Table) 이라는 것을 유지한다. 하위 클래스가 메서드를 호출할 때, vTable 을 참조하여 실제 호출할 함수를 결정한다. 이 과정이 런 타임에 일어나기 때문에 컴파일 타임에 비해 성능상 손해를 볼 수 있다.

 

 

 

☑️ vTable

그렇다면 vTable 은 뭘까? 클래스 내부의 함수들 중 어떠한 함수를 호출해야 할 지 결정하는 테이블이다. 즉, vTable 에서 지금 class 가 어떠한 함수를 호출해야 하는지 조회하고 해당 함수를 호출하는 방식이다. 이러한 과정이 런 타임 때 이루어지며 성능적인 측면에서 불리하다.

 

 

 그렇다면 final 은 왜 쓸까?

1. Dynamic Dispatch 성능의 문제점

Dynamic Dispatch는 런 타임 때 vTable을 찾아 메서드를 실행하기 때문에 성능상 손해를 본다. Swift의 class는 상속, 오버라이딩의 가능성 때문에 Dynamic Dispatch로 동작한다.

 

 

something 이라는 프로퍼티는 doSomething() 메서드를 실행할 때 Aclass 를 참조해야할지, Bclass 를 참조해야할지 런 타임 시점에 vTable을 통해 결정이 된다. 이처럼 class는 오버라이딩의 가능성 때문에 Dynamic Dispatch로 동작한다.

 

 

2. Static Dispatch 를 통한 성능 최적화

만약 상속이 필요없는 클래스나 메서드, 프로퍼티에 final을 붙이게 된다면 더이상 상속이 불가하게 된다. 

 

위와같이 final 키워드를 붙여 Dynamic Dispatch 과정이 필요 없음을 명시해주며, Static Dispatch로 동작하게 된다. Static Dispatch를 사용해 컴파일 타임에 호출할 메서드를 지정함으로 런타임 성능이 향상하게 된다.

 

 

 

 

 

 정리: class는 Dynamic Dispatch 방식으로 이루어지기 때문에, 상속이 되지 않는 class라면 final을 붙여 Static Dispatch 방식으로 바꾸는게 성능적으로 이점이 있다.

 

 

 

 

 

 

 


 

 

출처: https://babbab2.tistory.com/145?category=828998

https://pc.net/helpcenter/answers/compile_time_vs_runtime