[Sesac IOS] 39일차 TIL
TIL

[Sesac IOS] 39일차 TIL

39일차 수업 내용을 정리한 글입니다.


Learned

높은 성능의 Swift Code를 작성하는 방법

1. 최적화 활성화

  • Swift는 코드를 최적화하기 위해 설정할 수 있는 3가지 레벨 (optimization level)을 제공하고 있으며
    각 레벨마다 최적화의 수준이 다르다.
  • Onone: 최소한의 최적화를 수행하고 모든 디버그 정보를 보존함. 주로 Debug 모드에서 사용됨.
  • O: 대부분의 Release 모드(제품 출시용 코드)에서 사용되는 최적화 레벨로서, 컴파일러가
    적극적으로 최적화를 수행하며 디버그 정보가 손실될 수 있음.
  • Osize: 컴파일러가 성능보다 코드의 크기를 우선 시 하여 최적화를 수행함.

2. Whole Module Optimization (WMO)

  • Swift는 기본적으로 각 파일을 개별적으로 컴파일하기 때문에
    여러 개의 파일을 동시에 빠르게 컴파일 할 수 있음.
  • 하지만 각 파일을 별도로 컴파일하는 것은 특정 컴파일러 최적화를 막는다는 단점이 있음.
  • 따라서 Swift에서는 전체 프로그램을 마치 하나의 파일처럼 컴파일하고
    프로그램을 하나의 컴파일 단위처럼 최적화할 수 있는 WMO 모드를 제공함.
  • 이 모드를 사용하면 프로그램을 컴파일하는 시간이 오래 걸리지만
    컴파일이 완료되면 더 빠르게 실행된다는 장점이 있음.

3. Dynamic Dispatch 줄이기

  • Swift는 기본적으로 Objective-C와 같은 동적 언어이지만 Objective-C와 다르게
    필요에 따라 역동성(dynamism)을 줄임으로써 런타임 성능을 향상시킬 수 있음.
정적 언어와 동적 언어

정적 언어
컴파일 시 모든 변수의 타입을 결정하는 언어로, 프로그래머가 변수에 들어갈 값에 따라 직접 타입을 결정해줘야 함.
컴파일 시에 모든 타입이 결정되어 속도가 빠르고 타입 오류를 초기에 발견할 수 있음.
ex) C, C#, C++, Java 등

동적 언어
런타임 시 모든 변수의 타입이 결정되는 언어로, 일일히 타입을 결정해줄 필요가 없어
코드 작성 속도가 빠르고 런타임까지 타입 결정을 미룰 수 있기 때문에 유연성이 높음.
ex) Python, JavaScript, Objective-C
  • 기본적으로 클래스 타입은 메서드와 프로퍼티에 접근할 때 Dynamic Dispatch를 사용하는데,
    Dynamic Dispatch는 vTable를 이용한 간접적 호출(indirect invoke)로 인해
    자체적으로 오버헤드를 발생시키고 컴파일러의 최적화를 막기 때문에 직접적인 호출보다 속도가 느리다.
  • 따라서 프로그래머는 자체적으로 Dynamic Dispatch를 줄여서 성능이 향상된 코드를 작성할 수 있음.
Method Dispatch
프로그램이 어떤 메서드를 호출할 지 결정하고 그 메서드를 호출하는 과정을 의미함.
호출할 메서드를 결정하는 시점에 따라 Static Method DispatchDynamic Method Dispatch로 나뉨.

- Static Dispatch
컴파일 시점에 컴파일러가 메서드의 실제 위치를 알고 있어서 런타임에 찾을 필요 없이
코드를 바로 실행하는 것을 의미하며, 메서드의 위치와 구현된 코드를 미리 알고있기 때문에
메서드 인라이닝(Method Inlining)같은 코드 최적화를 적극적으로 수행함.

- Dynamic Dispatch
컴파일 타임에 어떤 메서드를 호출할 지 판단할 수 없어서 런타임에 vTable를 참조하여
호출할 메서드를 찾고 해당 메서드를 실행하는 것을 의미함.
대표적으로 클래스의 다형성(Polymorphism)을 위해 제공하는 오버라이딩으로 인해
호출해야 하는 정확한 메서드를 찾기 어려워 항상 런타임에 확인하는 작업이 필요함.

최적화 팁

1. final 키워드 사용

  • final 키워드를 사용해 클래스, 메서드, 프로퍼티가 재정의될 수 없도록 제한하여
    Dynamic Dispatch를 Static Dispatch로 사용할 수 있음.
  • final로 선언되면 재정의 및 상속이 되지 않기 때문에 컴파일러가
    어떤 메서드를 호출해야 하는지 알 수 있음.
  • 따라서 final로 선언된 경우 컴파일 시점에 호출할 메서드를 알고 있어서
    Dynamic Dispatch없이 직접 접근이 가능하여 성능 상에 이점이 있음.
static func vs class func
static으로 선언된 타입 메서드는 기본적으로 상속이 불가하지만 class 키워드로 가능하게 만들 수 있음.
final class func은 static func과 동일하게 인식됨.

2. fileprivate, private 접근 제어 사용

  • 클래스, 메서드, 프로퍼티가 선언된 파일의 외부에서 해당 선언에 접근할 필요가 없는 경우
    private, fileprivate 접근 제어자를 사용해 가시성을 제한할 수 있음.
  • 이렇게 하면 컴파일러는 잠재적으로 모든 오버라이딩 선언을 확인할 수 있고
    상속 및 재정의되지 않은 경우 자동으로 final 키워드를 추론하여 직접 접근이 가능함.

3. WMO 모드에서 internal 접근 제어 사용

  • WMO가 활성화 된 경우 컴파일러는 모듈의 전체 소스파일을 한꺼번에 컴파일하는데,
    이 때 최적화 도구가 모듈 전체(클래스, 메서드 선언 등)에 대한 가시성을 가질 수 있음.
  • 그리고 internal로 제어된 선언은 외부 모듈에서 볼 수 없기 때문에 
    최적화 도구는 내부적으로 상속 및 재정의되는 모든 선언을 확인하고
    그 중에서 final을 유추하여 Dynamic Dispatch를 제거할 수 있음.
Swift의 기본 접근 제어 레벨은 internal이기 때문에 WMO를 활성화하면 추가 작업 없이 최적화할 수 있음.

 


이상입니다.

참고자료 : https://corykim0829.github.io//swift/Understanding-Swift-Performance/#

 

[Swift] 스위프트 성능 이해하기 (1) - struct와 class의 성능 차이

struct와 class의 성능에 대해 자세히 알아보자

corykim0829.github.io

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

 

GitHub - apple/swift: The Swift Programming Language

The Swift Programming Language. Contribute to apple/swift development by creating an account on GitHub.

github.com

https://stackoverflow.com/questions/29924477/is-swift-a-dynamic-or-static-language

 

Is Swift a dynamic or static language?

I'm just curious if Swift is dynamic like php or static, I mean can I generate classes while an application is running?

stackoverflow.com

https://devuna.tistory.com/82

 

정적타입 언어 vs. 동적타입 언어 특징 비교하기

[Groovy] 정적타입 언어 vs. 동적타입 언어 특징 비교하기 자바를 사용하다 최근 그루비를 사용하며 개인적으로 느꼈던 가장 큰 차이 하나를 꼽자면 바로 자료형에 대한 명시 여부였습니다. groovy는

devuna.tistory.com

https://developer.apple.com/videos/play/wwdc2016/416/

 

Understanding Swift Performance - WWDC16 - Videos - Apple Developer

In this advanced session, find out how structs, classes, protocols, and generics are implemented in Swift. Learn about their relative...

developer.apple.com

 

'TIL' 카테고리의 다른 글

[Sesac IOS] 41일차 TIL  (2) 2022.08.31
[Sesac IOS] 40일차 TIL  (0) 2022.08.31
[Sesac IOS] 38일차 TIL  (0) 2022.08.25
[Sesac IOS] 37일차 TIL  (0) 2022.08.25
[Sesac IOS] 36일차 TIL  (0) 2022.08.24