EEYatHo 앱 깎는 이야기

Swift ) Class vs Struct 성능 비교 - EEYatHo iOS 본문

iOS, Swift/Swift Theory

Swift ) Class vs Struct 성능 비교 - EEYatHo iOS

EEYatHo 2023. 1. 6. 01:30
반응형

 

 

 

성능 비교의 3가지 관점


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

 

 

 

 

Allocation


  • Stack 은 LIFO 구조 및 Pointer 를 이용해서 할당, 해제하기에 간단한 만큼, O(1)의 빠른 속도를 가짐
  • Heap 은 사용하지 않은 블럭을 찾아서 할당하고, 해제한 블럭을 적절한 곳에 재삽입해야하고,
    thread-safe 를 위해 locking 또는 기타 동기화 기법을 사용해 무결성을 보호해야하기에, Stack 보다 느린 속도를 가짐

  • Stack 은 Value-Sementics 를 할당하며, struct, enum, tuple, 기본타입들이 있다.
  • Heap 은 Reference-Sementics 를 할당하며, class, closure 이 있다.

  • struct 는 stack 에, class 는 Heap 에 할당되기 때문에 struct 의 승리

 

 

 

 

Reference Counting


  • Heap 에 있는 인스턴스는, 해제할 타이밍을 알기위해 자신을 참조하는 인스턴스들의 갯수를 표시하며 이를 레퍼런스 카운트라 함
  • 레퍼런스 카운트인스턴스 자신이 가지고 있음
  • 레퍼런스를 증감시키는 것은, Heap 할당과 마찬가지로 무결성을 보호하기 위한 오버헤드가 있음
    레퍼런스 카운트가 필요없는 Stack 을 사용하는 Value-Sementics 들이 좋고, struct의 승리

 

  • One more Step
    • struct 지만, 내부적으로 class 들을 사용하면, 그만큼 Reference Counting 이 발생함
      ( struct 안에 2개의 class 인스턴스가 있다면, Reference Counting 2개가 발생 )

    • 즉, struct 라도 class 보다 더 많은 Reference Counting 을 발생시킬 수 있음
      ( 2개의 class 인스턴스를 가진 struct 와, 2개의 struct 인스턴스를 가진 class
      struct 가 Reference Counting 이 더 많다 )

 

  • 내 생각 : 많은 n개의 참조를 가진 데이터는 class 가 좋을 수 있다 
    • 처음엔 당연히 모든걸 struct 로 구현하면 좋겠는데?
      struct 안에 n개의 class 인스턴스라면, Reference Counting n개 발생,
      class 안에 n개의 class 인스턴스라면, Reference Counting n + 1개가 발생하니까?!

      -> 해당 인스턴스를 복사할 때 class 가 더 났다.
      class 는 Reference Counting 1개가 발생하고,
      struct 는 Reference Counting n개가 발생하기 때문

 

 

 

Method Dispatch


  • 어떤 메소드를 호출할지 결정하여, 그 메소드를 호출하는 과정
  • 어떤 메소드인지 결정되는 시점에 따라 static dispatchdynamic dispatch 로 나뉘게됨
    • static dispatch
      • 컴파일타임에 어떤 구현을 실행할지 결정할 수 있음
      • 컴파일시 메소드 인라이닝 (Method Inlining) 과 같은 코드 최적화를 시행
        • 메소드 인라이닝 : 메소드 호출부를 메소드 구현부로 대치시켜서 호출 과정을 생략하는 최적화 기법
    • dynamic dispatch
      • 런타임에 어떤 구현을 실행할지 결정할 수 있음
      • 어떤 메소드를 실행할지 결정하고 해당 메소드로 jump 하여 코드 실행
      • 컴파일러의 가시성(visibility)을 막기 때문에, 최적화에 악영향

 

  • dynamic dispatch 를 쓰는 이유 : 다형성 (polymorphism) 이라는 강력한 기능을 위해
    • 아래의 코드에서 forEach 안의 구문이 어떤 int, myFunction 을 실행해야하는지 컴파일 타임에는 알 수 없음
class A {
    var int: Int = 0
    func myFunction() {}
}
class B: A {
    var _int: Int = 0
    override var int: Int {
        get { _int * 2 }
        set { _int = newValue * 2 }
    }
    override func myFunction() {}
}
class C: A {
    var _int: Int = 0
    override var int: Int {
        get { _int * 3 }
        set { _int = newValue * 3 }
    }
    override func myFunction() {}
}

let a = A()
let b = B()
let c = C()

let arr: [A] = [a, b, c]

arr.forEach {
    $0.int = 2
    $0.myFunction()
}

 

  • dynamic dispatch는 해당 타입의 vtable에 접근하여 정확한 프로퍼티, 메소드에 접근
    vtable 설명 링크
    원문 : A virtual method table or 'vtable' is a type specific table referenced by instances that contains the addresses of the type's methods. Dynamic dispatch proceeds by first looking up the table from the object and then looking up the method in the table.
$0.type.vtable.int = 2 // $0.int = 2
$0.type.vtable.myFunction() // $0.myFunction()

 

 

  • class 에서 dynamic dispatch 피하기
    • class 에 final 구문을 사용하면, 해당 클래스의 프로퍼티와 메소드는 더이상 상속하지 않기에,
      컴파일러가 static dispatch 를 진행하고 최적화를 진행할 수 있음

    • 이는 프로퍼티, 메소드들에게 각각 적용
      class가 final이 아니어도, 메소드에 final을 붙히면 static dispatch를 진행 

    • 참고 링크

 

  • 따라서
    class 는 다형성 때문에 dynamic dispatch
    final class, struct 는 더이상 상속하지않기에 static dispatch
    로 나눌 수 있다

 

 

 

 

Reference


 

 

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

 

 

 

Swift ) (1) Understanding Swift Performance (Swift성능 이해하기)

안녕하세요 :) Zedd입니다.저번글이 OptimizationTips였는데요, 이걸 제가 완벽히 이해하지 못한 부분이 딱 하나 있는데, 바로 "Swift에서 타입은 값타입(구조체, 열거형, 튜플..) 및 참조타입(클래스)의

zeddios.tistory.com

 

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

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

corykim0829.github.io

 

 

 

GitHub - apple/swift: The Swift Programming Language

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

github.com

 

 

 

Comments