Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

class의 성능을 향상 시킬수 있는 방법들을 나열해보시오. #2

Open
Do-hyun-Kim opened this issue Jul 25, 2023 · 4 comments
Labels
Swift Swift CS 개념 공부

Comments

@Do-hyun-Kim
Copy link
Contributor

No description provided.

@Do-hyun-Kim Do-hyun-Kim added the Swift Swift CS 개념 공부 label Jul 25, 2023
@vichye-1
Copy link

스위프트 코드에서 성능에 영향을 주는 요소

  • Allocation : 인스턴스를 생성하면 Stack과 Heap 중 어느 곳에 할당되는지
  • Reference Counting : 인스턴스를 통해 레퍼런스 카운트가 몇 개가 발생하는지
  • Method Dispatch : 인스턴스에서 메소드를 호출했을 때, 메소드 디스패치가 정적인지 동적인지

클래스의 특징

클래스는 기본적으로 heap allocation을 사용하고, 이로 인해 reference counting이 발생한다. 또한 dynamic dispatch로 메소드를 호출한다.

<요소별 성능 향상 방법>

Allocation

  • struct 를 사용한다
    • stack 은 heap 보다 비용이 더 적게 들어가며, 속도가 더 빠른 할당 방법이다. 따라서 heap allocation을 하지 않는 struct를 적절히 활용하여 성능을 향상시킬 수 있다.

Reference Counting

  • 약한 참조 사용
    • class는 ARC로 앱의 메모리를 관리한다. 클래스 인스턴스 간에 강한 참조가 발생하면 메모리가 정상적으로 해제되지 않고 메모리 누수가 된다. 이를 위해 강한 참조를 약한 참조로 변경하거나, 강한 순환 참조를 막기 위해 약한 참조를 사용하여 순환 참조를 적절하게 끊을 수 있다.

Method Dispatch

  • 상속되지 않는 class 에는 final 키워드를 붙여준다.
    • final을 클래스 앞에 선언하여 컴파일러가 Static Dispatch하게 할 수 있다.
    • 상속을 방지하고 재정의를 막을 수 있다.

📝 참고

@ronick-grammer
Copy link
Contributor

ronick-grammer commented Jul 27, 2023

Dispatch

메서드를 호출할 때, 어떤 메서드(or 프로퍼티)를 호출할지 결정하는 메커니즘

  • Static Dispatch: 컴파일 시점에 어떤 메서드(or 프로퍼티) 를 호출할지 결정한다. 값 타입인 struct, enum 에서는 메서드 호출시 Static Dispatch를 통해서 즉시 메서드를 호출한다(Direct Call). Dynamic Dispatch가 동작할 때보다 성능적 이점이 있다.

  • Dynamic Dispatch: 런타임 중에 어떤 메서드(or 프로퍼티)를 호출할지 결정한다. 때문에 성능적 오버헤드가 따른다. vTable(Virtual Table)에서 호출해야하는 정확한 메서드를 런타임중에 찾게된다. 참조 타입인 class 에서 메서드 호출시 Dynamic Dispatch 를 통해 vTable에서 호출해야하는 메서드의 메모리 주소를 찾아 호출한다(Indirect Call). class는 상속이 가능하고 따라서 override 역시 가능하기에 상속관계에 있는 subclass가 어떤 메서드를 호출해야하는지 결정해야하기 때문이다.
    *(설령 superclass 를 상속하는 subclass 가 없거나 override 하는 메서드(or 프로퍼티)가 없다고 하더라도 그 가능성으로 인해 class 는 Dynamic Dispatch 메커니즘에 메서드(프로퍼티) 호출이 결정된다)

class에서 Static Dispatch 가 실행되도록 하는 방법

final 키워드 사용

  • class 선언부에 final 키워드를 사용하여 class 내부의 모든 메서드, 프로퍼티가 상속관계에서 오버라이딩 불가능함을 컴파일러에게 알려 Static Dispatch가 동작하도록 한다.

  • class 내부에서 선택적으로 메서드, 프로퍼티에 final을 사용하여 이들이 상속관계에서 오버라이딩이 불가능함을 컴파일러에게 알려 Static Dispatch가 동작하도록 한다.

private 키워드 사용

  • class 선언부에 private 키워드를 사용하여 class 내부의 모든 메서드, 프로퍼티가 상속관계에서 오버라이딩이 되지 않을 경우 컴파일러가 final 로 자동 추론하여 Static Dispatch가 동작하도록 한다.

  • class 내부에 선택적으로 메서드, 프로퍼티에 private를 사용하고 이들이 상속관계에서 오버라이딩이 되지 않을 경우 컴파일러가 final로 자동 추론하여 Static Dispatch가 동작하도록 한다.

WMO(Whole Module Optimization) 사용

  • Xocde 프로젝트 세팅에서 compilation modeWhole Module 로 설정(기본으로 설정되어 있음)

  • 일반적으로 컴파일러는 파일단위로 컴파일을 하여 한 파일의 클래스를 다른 파일의 클래스가 상속을 할때 오버라이딩하는 메서드(or 프로퍼티)가 없으면 final로 자동 추론을 할 수가 없다. 하지만 WMO 로 설정되어 있으면 모듈단위로 컴파일하여 각 다른 파일에 존재하는 클래스들간의 상속관계에서 오버라이딩이 없을 경우 final로 자동 추론이 가능하게 되어 Static Dispatch 가 동작되도록 한다.

📝 참고 사이트

@Do-hyun-Kim
Copy link
Contributor Author

Method Dispatch

어떤 메서드(Static, Dynamic)호출할 것인가를 결정하고 실행하는 과정을 의미한다.

Static Dispatch

  • 컴파일 타임에 실제 호출할 함수를 결정할
  • 컴파일 시점에서 정하기 때문에 Dynamic Dispatch보다 비교적 빠르다.
  • 주로 값 타입(Value Type) 에서 사용하게 된다.
  • 최적화 기법중 하나인 Method Inline을 사용할 수 있다.

Dynamic Dispatch

  • Reference Semantics 에서의 다향성은 컴파일 시점에서 어떤 클레스의 메서드인지 알 수 없기에 런타임 시점에 호출할 함수를 결정한다.
  • 런타임 시점에서 호출할 함수를 정하기 때문에 Static Dispatch보다 느리다.
  • Dynamic Dispatch 같은 경우 Virtual Dispatch Table 함수 포인터 배열을 유지하여 하위 클래스에 메서드를 호출 할때 마다 Virtual Dispatch Table에 참조하여 실제 호출할 함수를 결정하며 이러한 과정이 런타임에 결정 되기 때문에 추가적인 연산이 필요 하며, 시간적인 측면에서 Static Dispatch 보다 느릴 수밖에 없다.

class의 성능을 향상 시킬수 있는 방법

  • Inheritance, Overriding이 필요 없는 클래스 인 경우 final 키워드를 사용하여 Static Dispatch로 동작 하도록 구현 한다.
  • 접근 제어자 중 하나인 private 키워드를 사용하여 컴파일 시점에Overriding가 없다는 것을 알려주며 Static Dispatch로 동작 하게 한다.

📝 참고 사이트

@Hminchae
Copy link
Member

Hminchae commented Aug 3, 2023

1. Static Dispatch 사용

class뿐만 아니라 상속, 오버라이딩 될 필요가 없는 클래스, 메서드, 프로퍼티에 final 키워드를 붙여 Static Dispatch를 통해 성능 향상을 기대할 수 있다.

Static Dispatch?

  • 호출할 메서드를 컴파일 타임에 결정, 런타임때 호출할 메서드를 이미 결정했으니 성능이 좋음

dynamic Dispatch?

  • 호출할 메서드를 런타임에 결정, Swift는 dynamic Dispatch를 지원하기 위해 클래스마다 함수 포인터들의 배열인 vTable(Virtual Method Table)을 갖고있음
  • 하위 클래스가 상위의 메서드를 호출할 때 vTable을 런타임 시점에 참조하여 실제 호출할 함수를 결정하기 때문에 성능이 떨어짐

2. 파일내에서만 접근해도 될 경우에는 private 키워드를 붙인다.

  • Static Dispatch와 비슷하게 private 키워드를 사용하면 컴파일러가 잠재적으로 private 키워드가 참조될 수 있는 곳에서 오버라이드 하고 있는지 판단함
  • 이때 오버라이딩이 되고 있지 않다면 스스로 final 키워드를 호출하여 동작함
  • cf. class 에 private 키워드를 붙이면 내부의 모든 프로퍼티와 메서드에도 private 키워드가 붙여져 있는 것으로 판단함

3. Whole Module Optimization(WMO)를 사용

WMO는 컴파일러의 최적화 모드이며 컴파일러 플래그를 이용하여 켤 수 있다.

  • WMO 사용 시, 컴파일러가 모듈에 있는 모든 함수의 구현을 확인하므로 함수에 대한 최적화를 수행할 수 있음
  • 또한 모듈 내에서만 사용되는 비공개 함수에 대한 모든 사용을 추론하여 사용되지 않는 함수를 제거하여 최적화를 수행할 수 있음

📝참조

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Swift Swift CS 개념 공부
Projects
None yet
Development

No branches or pull requests

4 participants