ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift Performance
    Swift 2021. 3. 1. 17:03

    안녕하세요. 그린입니다!

    이번 포스팅에서는 Swift Performance, 스위프트 퍼포먼스에 대해 이야기 해볼까 합니다😃

     

    우선 Performance는 뭐라고 생각하면 좋을까요?

    저는 퍼포먼스가 성능이라고 생각됩니다.

    같은 애플리케이션을 구현하더라도 클래스로 구현하냐 구조체로 구현하냐에 따라 앱 성능 차이가 있을겁니다.

    이러한 앱의 성능을 최대한으로 이끌어낼 수 있어야 좋은 앱이라고 할 수 있겠죠??🙌

     

    • 성능을 자료구조에서는 어떤식으로 표현해볼 수 있을까요?

     : 시간복잡도 (빅오 표기법, Big O)로 표현해볼 수 있습니다.

     

     

    • 시간복잡도?

     : 코드 알고리즘의 성능을 특수한 표현으로 나타낸 표기법으로 성능이랑 연관되어 있습니다.

     : 예를들어 이중 for문을  시간복잡도로 나타내면 O(N^)으로 나타낼 수 있습니다. 정확하게는 O(N^+2)와 같지만 여기서

       +2처럼 큰 사이즈에서 결과에 영향을 미치는 부분이 작다면 무시하고 표기할 수 있습니다.

     

     

    • Swift에서의 예시

     : 배열과 딕셔너리를 예를 들어 시간복잡도를 생각해 볼 수 있습니다.

     : 배열은 해당 자료를 탐색하려면 최악의 경우 전체 인덱스를 다 접근해야함으로 O(N)이 되고

       딕셔너리는 키와 값이 있기에 O(1)의 시간복잡도를 가짐으로 딕셔너리가 더 나은 성능을 발휘할 수 있습니다.

     : 배열에서도 reverse()와 reversed() 메서드가 있는데 비슷한 역할을 하지만 다른 시간 복잡도를 가집니다.

       -> reverse()는 배열의 순서를 반전시켜 다시 저장시킴으로 O(N),

            reversed()는 배열의 순서를 반전시켜 새로 저장시킴으로 O(1)의 시간 복잡도를 가집니다.

     

     

    • 성능에 영향을 주는 3가지 사항

     : WWDC2016에서도 소개되었는데 아래 그림과 같이 스위프트 성능에 크게 3가지 영향으로 나타낼 수 있습니다.

     1) Allocation: 인스턴스의 저장 위치, 즉 할당의 의미를 지닙니다. (Stack or Heap)

     : 스택은 함수 호출과 함께 할당되고 완료되면 소멸 (스택포인터를 변수 값으로 관리 가능)

     : 힙은 동적이여서 성능에는 덜 효율적 (오버헤드가 많을 경우 스레드 안정성을 체크하고 무결성을 지켜야하기에)

     : 배열은 값 타입 사용이 권장된다. (클래스 사용 시 NSArray로 사용될 수 있어 컴파일러 최적화가 불가능하다)

     -> ContigousArray로 사용하면 요소들이 메모리에 매번 연속적으로 저장됨으로 클래스 사용 시 권장된다.

     : 오버플로우가 발생하지 않는 조건에서도 해당 오버플로우가 발생하는지 안하는지 체크하는것만으로도 성능에 영향을 준다.

     -> Swift Flags에 추가하여 전처리기 사용으로 분기처리를 하면 성능에 도움이 된다.

    -. 요부분에 추가

     

     2) Reference Counting: 참조 횟수 (ARC와 연관)

     : 힙 메모리를 위해 사용되고 있는 ARC

     : Strong, Weak, Unowned에 따라 성능이 다름 (참조 종류에 따라)

      -> Weak: 참조하는 인스턴스가 메모리에서 해제 시 ARC가 자동으로 참조를 nil로 변경

          (추적 후 nil로 변경함으로 오버헤드가 발생될 수 있음)

     -> Unowned: ARC가 참조 값을 nil로 변경하지 않음 (오버헤드 발생하지 않지만 없는 값을 참조할 때 앱 크래쉬가 날 수 있음),

          참조하는 인스턴스가 항상 메모리에 존재할거라는 확신?이 있을때 사용

     : Class VS Struct

     -> Class는 Reference Counting이 존재

     -> Struct는 Stack 메모리에 할당되어 Reference Counting 미존재

     -> String, Array, Dictionary의 타입은 값 타입인데 Class 타입을 가지고 있다??

         (COW(Copy On Write)를 위해... copy 시 Reference Counting 발생)

     

     3) Method Dispatch: 메서드 호출 시 디스패치 종류 (Static or Dynamic), 실행하는 코드의 메모리 주소를 탐색하는 프로세스

     : 메서드 디스패치의 종류로는 크게 Static과 Dynamic이 있고, Dynamic에서는 Table과 Message Dispatch로 구분된다.

     : 스위프트에서는 위 3가지의 메서드 디스패치를 모두 갖고있다.

     : Static

     -> 가장 빠름

     -> 컴파일 중 호출 메서드를 알고 처리 (메서드 인라이닝 방식)

     : Dynamic

     -> 클래스의 메서드 주소 저장을 위한 포인터 배열 생성 (Table로 호출되어 런타임 시 Table 조회)

     : Dynamic 방식의 Class를 Static 방식으로 변경하는 방법?

     -> final, private, fileprivate과 같은 접근제한자를 선언해줌으로써 상속이 없는 클래스라는걸 명시하여 방식을 변경한다.

     

     

    • 보다 빠른 성능의 조건

     1) Stack에 인스턴스 할당

     2) Reference Counting 적음

     3) Static Dispatch

     

     

    [정리]

    오늘 스위프트 퍼포먼스에 대해 이정도 이해를 하였는데 너무너무 어려운 부분인것같다...

    더 확실한 이해를 하기 위해 공부를 계속 해보면서 하나씩 차근차근 이해해봐야겠다.

    잘 아직 결론이 안난 부분은 두가지이다.

    1) 구조체니까 추상화하는 과정이 있어야하는데 추상화의 성능을 좋게하려면 위의 3가지 조건이 필요하다는말..???

    2) 클래스는 힙/레퍼런스 카운팅/다이나믹 메서드 디스패치 위 성능이 좋지않은 3가지 조건을 모두 사용하는데 그럼 왜 클래스를 사용할까? 상속때문에?? 더 좋은 방법은 없을까???

     

    더 공부하고 보완해봐야겠습니다👀

     

    [참고자료]

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

    https://zeddios.tistory.com/596

    https://hucet.tistory.com/85

    https://www.wwdcnotes.com/notes/wwdc16/416/

    'Swift' 카테고리의 다른 글

    GCD & Operation  (0) 2021.04.09
    lazy var  (0) 2021.03.17
    ARC 심화  (0) 2021.02.17
    Type Casting  (0) 2021.01.29
    Protocol Oriented Programming  (0) 2021.01.28
Designed by Tistory.