티스토리 뷰

이번에 WWDC에서 Understanding Swift Performance를 들었는데 참 좋은 내용인것 같아서 블로그에 남겨보려 한다

(라기보단 사실 티머니 스터디 인증을 위한..)

아무튼 이번주에는 Struct, Class의 성능 (Allocation, Reference Counting, Method Dispatch)에 대해 들었는데,

자세한 기록은 https://spark-chive-e55.notion.site/WWDC16-Understanding-Swift-Performance-1-b6828c991e2b4e0188f886bb4196d312 이 링크에서 보면 됩니다 

(예시 같은 것도 링크에 전부 정리했어요!!!!!)

이 글에는 내 의식의 흐름과 ,, 내가 정리하고 싶은 대로 정리해보겠습니다~!

 

Struct, Class 어느 것을 써야 더 성능에 좋을까

이 둘의 성능을 결정하는 요소는 세 가지가 있다.

1. Allocation (할당): 객체가 메모리에 allocation 될 때, Stack에 할당되는가? Heap에 할당되는가?

2. Reference Counting: 객체를 주고 받을 때, 얼마나 많은 reference counting overhead가 발생하는가?

3. Method Dispatch: 객체 내의 method를 호출할 때, Static dispatch를 사용하는가? Dynamic Dispatch를 사용하는가?

 

-> 기본적으로 생각해야 할 내용은 이유 없이 런타임에 비용을 쏟거나 Dynamism한 코드는 성능을 나쁘게 한다는 것!

이 점이 가장 큰 전체적인 흐름을 잡고있는 부분이다.

 

이 글에서는 Allocation 부분만 정리해보겠다

 

Allocation (할당)

객체가 메모리에 allocation 될 때, Stack에 할당되는가? Heap에 할당되는가?

-> 결론부터 이야기 하면 Stack 에 할당되는게 Heap 에 할당되는 것보다 빠르고,

Struct는 Stack에, Class는 Heap에 할당된다.

(그래서 예전에 어디선가 Struct가 Class보다 빠르다는 말을 들었구나..)

 

Swift의 메모리 구조중 Stack 과 Heap

1) Stack

- 컴파일 타임에 크기가 결정되는 부분

- CPU 에 의해 관리됨, 최적화 됨 -> 속도 빠름!!!!!!

- 정말 간단한 자료구조이다. (스택의 포인터 하나만으로 자료를 관리할 수 있음)

- 위 그림을 보면 메모리의 높은 주소 -> 낮은 주소 순으로 할당된다. 

   그렇기에, Stack pointer를 증가시켜서 Deallocate 하고, Stack pointer를 감소시켜서 Allocate한다.

  (이 말이 처음엔 이해가 잘 안됐는데, 그림 보니 바로 이해됨)

 

 

2) Heap

- 런타임에 크기가 결정되는 부분

- 스택보다 효율적이진 않지만 스택이 할 수 없는 일들을 한다.

- 스택보다 비용이 많이 든다.

   1. 스택보다 Allocate, Deallocate에 비용이 더 많이 드는 구조라고 한다. -> 하지만 이가 주요한 요소는 아니고

   2. Thread safety overhead -> 이친구가 비용이 참 많이 든다. 

       여러 스레드가 동시에 힙에 메모리를 할당하는 것을 막기 위해 힙을 잠그거나 기타 동기화 메커니즘을 사용해서 막아야하는 것을 이야기한다. (CS 지식을 열심히 공부하자!)

 

아무튼 이러한 특징 때문에 스택이 훨씬 힙보다 빠른 성능을 자랑한다.

 

예시

Struct는 위에도 말했듯이 Stack에 저장되어 빠른 성능을 자랑한다.

스택에 값이 바로 저장되기 때문에

`var point2 = point1` 코드에서 point2에 point1 부분이 바로 복사되어 저장되는 것을 볼 수 있다.

그렇기에 point2.x = 5를 대입해도 point1.x는 여전히 0이다.

(오! Call by Value!)

 

Class 같은 경우는 Stack의 경우와 조금 다르다.

Class가 가진 값들은 Heap 영역에 저장되고, Stack 부분에는 Heap영역의 reference값이 들어간다.

그래서 `let point2 = point1`을 하면 point1의 스택부분에 있는 reference값이 point2의 스택부분에 복사가 되고,

결과적으로 point1과 point2가 같은 reference를 가지고 있기에 heap영역의 같은 부분을 가리키게 된다.

-> heap영역의 자원을 공유하게 된다.

그래서 point2.x=5 로 하면 point1.x도 point2와 같은 레퍼런스를 가지고 있기에 5로 변한다.

(오 Call by Reference~)

 

그럼 위에 파란 부분은 뭐냐하면 Swift가 자동으로 이러한 것들을 관리해주기 위한 공간이라고 한다.

 

Class가 메모리에 할당되는 자세한 과정은 이 글 상단에 있는 노션 링크에 가면 자세히 볼 수 있다!!! (개인적으로 보면서 신기했다)

 

Allocation 결론

위에도 말했듯 Struct는 Stack에, Class는 Heap에 할당되기에 결론적으론 아래와 같은 성능을 볼 수 있다.

물론, Class를 써야만 하는 경우도 있다. (identity, indirect storage라는 특징은 Class만 있으니까!!)

하지만 Class를 쓰게 되면 Heap할당이 많아진다는 뜻이고, 그만큼 성능이 좋지 않다는 뜻이니까

굳이 쓸 필요 없다면 Struct를 쓰도록 하자!!

 

느낀점

지금까지는 그냥 Struct와 Class의 차이에 값타입, 참조타입, Struct가 빠름. 이런 내용만 이야기 외우다시피해서 이야기했던 것 같다.

그런데 이 속 내용을 알고 나니 참 신기하고 아 이게 이래서 그랬구나 싶은 내용들이 많았다.

뒤의 Reference Counting, Method Dispatch 내용도 참 흥미로운데 조만간 가져올게요 ~ (링크에는 정리되어있어요)

그리고 CS 공부를 열심히 하자.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함