XLOG

[Swift] Struct VS Class 본문

Swift/Etc

[Swift] Struct VS Class

X_PROFIT 2023. 3. 2. 21:02

작년 애플아카데미에서 프로젝트를 진행하면서 MVC, MVVM 아키텍쳐를 채택하고 자연스럽게 Model을 만들었다.

 

Model을 만들었을 때 모델은 클래스로 하느냐, 구조체로 하느냐에 대한 논의를 많이 했었다.

그 당시 구조체는 값, 클래스는 참조 이렇게 단순하게만 생각했다.

그래서 당시 멘토 비비에게 물어봤더니 WWDC16 의 Understanding Swift Performance 를 추천해줬었다.

 

영상에서 처음 Struct 와 Class 가 메모리에 어떻게 할당하는지를 보여준다.

Struct => Stack

Class => Heap

 

Stack 메모리는 push 와 pop 으로 동작하는 심플한 구조로 포인터는 맨 마지막을 가르키며 간단하게 동작을 한다.

하지만 힙은...? 사용되지 않는 메모리 공간을 찾아서 할당을 해줘야 하면 메모리에서 해제를 할때도 그 블럭의 위치를 찾아야 한다. 

훨씬 복잡한 동작으로 작동을 하기 때문에 더 느릴 수 밖에 없다. 

단순히 동작만이 아니다. 사용되어져야 하는 공간의 크기도 다르다. 

위의 사진의 경우 처럼 Struct 로 구성을 하게 되면 point1, point2 는 stack 메모리에 각각 독립된 두개의 공간을 차지 하고 있다.

하지만 아래의 사진과 같은 경우는 point1point2 는 stack 메모리에 Heap의 할당된 메모리 블럭을 참조할 값을 가지고 Heap 4개의 공간을 차지하고 있다. 2개가 아니고.... 즉 할당되는 공간의 크기도 비효율적이게 된다.

 

이렇게만 본다면 당연히 Struct 가 훨씬 효율적인 속도를 내는구나 생각할 수 있다. 하지만 여기엔 우리가 알아야 하는 문제가 존재한다.

 

위의 경우처럼 Label 의 구조체 내부에는 String(Class), UIFont(Class)를 포함하고 있다. 아까와 같은 방식이라면 text와 font 가 클래스를 참조해야 한다. 아까 Int로만 이루어진 구조체와는 또 다른 느낌이다. 훨씬 더 많은 메모리 공간을 필요로 한다. 즉 우리는 구조체 내부 속성들의 타입도 고려를 해야한다는 것이다.

Label 을 class로 만들었다면 stack 메모리의 point1, point2 는 heap 메모리의 pointer 값 하나씩만 할당을 받으면 될것이다. 위의 사진처럼 속성이 두개밖에 없고, 할당받은 상수또한 두개밖에 되지 않기 때문에 큰 차이가 없어 보일 수 있지만 우리는 항상 더 많은 속성을 가지고 있을때, 더많은 상수나 변수를 만들때까지 생각을 해봐야 하는 것 같다. 

물론 영상에선 class 로 만들었을 때를 비교해주기 보단 한 가지 방법을 알려준다.

여기서 나온 방법은 mimeType과 같이 일정한 조건이 있는 String의 값을 열거형으로 바꾸게 되면 메모리 효율을 올릴 수 있다고 한다.

 

정리하자면 

  1. 기본적으로 Struct 가 속도가 훨씬 빠르다.
  2. 속성들의 타입에 대한 고민을 같이 해줘야 한다.
  3. 가장 중요한 것일 수 있지만 값의 공유가 필요한지 필요하지 않은지가 중요하다. 퍼포먼스도 중요하지만 기능이 올바르게 작동해야 하기 때문에...
  4. model 을 설계할 때 외부 값에 캐스팅에 대한 것으로 고려 단순하게 만들었지만, 퍼포먼스 고려 enum 을 잘 활용하는 방법에 대한 고민을 해보자

정도의 생각이 나온다. 

공부를 할 수록 이전에 한 프로젝트들의 문제점들이 하나 둘 보이기 시작한다......