iyOmSd/Title: iOS Think🤔

[iOS] WWDC16 Swift Performance - 성능 이해하기

냄수 2020. 10. 8. 00:40
반응형

Swift에서 사용하는 타입들은

값타입, 참조타입으로 나뉘고

그에따라 Stack, Heap에 구분되서 저장되요

 

값타입이고 Stack에 저장되는 Struct

참조타입이고 Heap에 저장되는 Class

 

  • Struct 와 Class 아무거나 쓰면 안되나여..?
    ➡️ Swift에는 Stack과 Heap메모리 공간이 존재
    ➡️ 값복사는 Stack에 참조복사시 Heap 메모리 사용
  • Struct
    상속이 필요없는경우
    Thread에서 Safe한값을 사용할 수 있음(복사한 값은 다른 변수에 전혀 영향을 주지 않음)
    참조가아닌 복사를 원할 때
    연관된 값을 하나의 데이터 타입으로 만들 때
  • Class
    Value보다 Identity가 중요한경우 -> 모든 변수에서 같은 상태갖고있음
    상속이 필요한 경우
    다형성을 이용한 타입캐스팅이 필요한경우
  • Stack과 Heap...?
    • Stack➡️ LIFO 단순한 데이터 구조
    • ➡️ 매우 빠름 O(1)
    • Heap➡️ dynamic lifetime 가진 메모리 할당가능
    • ➡️ 효율은 Stack이 큼
    • ➡️ 할당.. 검색... 재삽입.. 복잡한 구조

 

더 자세하게 알아 보도록 할까요??

 

 

 

Struct은 어디에 저장될까요?

Struct니까 값타입이네 Stack에 저장되겟어...!

 

그렇지 않은 경우가 존재해요!!

어떤 경우냐면 String, Array, Dictionary, Set 등이 있어요

 

이 타입들은 내부데이터가 Heap과 혼용하는 방식을 사용해요

내부저장은 Class타입을 가지고있고

복사시에 Reference Count가 동작하구요

복사시에 COW를 이용해서 속도가 저하되는걸 방지하는거에요

 

혼란이 올 수 있어요.. 지금것 알았던 값타입들이 값타입이 아니라니...!

 

 

Class와 Struct에 대해서 더 자세히 봐볼까요?

 

 

Protocol을 채택해서 Struct를 만들 수 있는데

이런경우에는 같은 프로토콜을 채택하니까 Point, Line 모두 같은 배열에 넣을 수 있을 거에요

같은배열인데 구조체 크기가 다를 수 있잖아요??

 

Drawable크기가 Point와 같다고 가정하면
Line은 Point보다 크기가 더큰데

배열 공간에 어떻게 넣냐는 그런 원리를 설명하는 장면이에요

 

Existential Container를 이용해서 한다고 하는데요

 

이런식으로 크기가 커지면

Heap으로 다시 할당되서 참조하는 식으로 저장해요

 

 

Existential Container는 VWT를 참조하는 변수를 가지고 있어요

Existential Container의 생성과 해제를 담당해주는 역할을 하고

VWT는 프로토콜을 구현하는 타입마다 존재하고

변수의 라이프사이클을 관리해주는 역할을 한다고 생각하면되요

 

 

요약하면

 

우선 Value 타입이니까 값 전체가 복사가되요

Heap을 사용하지만 복사가일어나고

Reference Count는 사용하지않아요

 

3 words 이하인경우

새로운 Existential Container에 전체가 복사되구요

 

넘는경우

새로운 Existential Container를 생성하고

값 전체가 Heap에 새로 할당된 후 복사가 되요

아래그림처럼요

이작업은 성능면에서 좋지않겠죠??

복사할때마다 Heap에 할당해줘야 하는데

Heap은 할당하는 과정이 비용이 큰 작업이에요

메모리의 빈곳을찾고 관리해줘야하기때문이죠

 

이 부분을 개선하기위한 방법에는

Indirect Storage 방법으로

많은 변수들을 Class로 묶어서 뺌으로써 Reference Count를 이용하는거에요

 

Struct에 Class타입의 프로퍼티가 2개 면

복사할 때 Reference Counting이 복사할때마다 2번 씩일어나고 더많다면

더 많이 일어날거에요

이 작업이 성능면에서 보면 안좋다고 해요

 

대표적으로 회피하는 방법중 하나가

많이 구현 해보셧다면 해본적이 있으실거에요

String을 Enum타입으로 관리하는 이유중 하나에요 - 값 타입으로 대체

가독성이 좋기도하고 관리하기도 좋을 뿐더러 성능면에서도 좋아요

 

만약 Protocol을 채택한 Struct를 사용할때 Struct가 커보인다?!

위에서 말한 Indirect 방식을 사용해보세요:) - Heap할당 대신 RC이용

 

 

 

 

 

 

 

 

WWDC2016내용을 번역해준 자료를 보면서 공부했어요

www.slideshare.net/YongHaYoo/ss-63881606

반응형