한줄 요약 : WWDC 꿀잼
WWDC 입문
최근에 WWDC에 입문했습니다.
WWDC 입문이 좀 늦은 편이죠? 제가 멍청한 생각을 했거든요...
"어차피 공식 문서 내용이 WWDC 내용 아니야? 공식 문서만 있으면 WWDC는 없어도 돼!"
라고 생각했기 때문입니다.
근데 최근에 들으며 느낀 점은 WWDC는 너무너무너무 유익하다는 것입니다.
2차원이었던 지식이 3차원이 되는 느낌이랄까요?
Understanding Swift Performance에서 배운 점
가장 처음 입문했던 WWDC 영상은 WWDC16의 Understanding Swift Performance 입니다.
메모리 저장 위치, Reference Counting, Method Dispatch의 관점에서 Swift의 성능을 이해하는 세션인데요.
이 세션에서 가장 먼저 만나는 건 Stack 입니다.
Stack은 Value Type이 저장되고 Heap 보다 빠르다.
이 사실은 Swift를 조금이라도 공부한 사람은 모두 아는 사실일 것입니다.
1. 그럼 왜 Stack에는 Value 타입만 저장될까요? Reference 타입은 Stack에 저장하지 못할까요?
Reference 타입은 런타임에 크기가 변경될 수 있기 때문에 Stack에 저장하지 못합니다.
이것도 아는 사람이 많겠죠?
2. 그럼 크기가 변하는 것과 Stack은 무슨 상관일까요?
Stack은 push, pop를 이용해 마지막 원소만 다룰 수 있어서 고정된 크기만 쌓을 수 있기 때문입니다.
이전의 저는 여기까지만 대답할 수 있었어요.
근데 뭔가 개념이 허전하지 않나요?
Stack이 top만 다룰 수 있는거랑 고정된 크기랑 무슨 상관이죠??
이 허전함을 Understanding Swift Performance에서 채울 수 있었습니다.
먼저, Stack과 고정된 크기는 무슨 연관이 있을까요?
Swift의 스택은 스택 포인터라는 것을 사용합니다.
스택 포인터를 이동 시켜서 메모리를 할당하고 해제하죠.
메모리가 할당되면 스택 포인터를 증가시키고, 메모리를 해제하면 스택 포인터를 감소시킵니다.
따라서 스택 포인터의 정확한 증감을 위해 이미 할당된 메모리의 크기가 변하면 안 되는 것이죠.
이 스택 포인터를 이해하면 top만 다룰 수 있다는 의미도 해결됩니다.
A, B, C를 쌓았을 때 스택 포인터는 A + B + C 크기 만큼의 위치에 있겠죠.
스택 포인터를 이동시켜 메모리 해제를 하기 때문에 C를 스킵하고 B나 A의 메모리를 해제할 수 없습니다.
또 스택 포인터를 이용한 메모리 할당/해제는 단 한 번의 증감 연산으로만 가능하기 때문에 Heap보다 빠르다는 것도 이해할 수 있습니다.
WWDC에서 알게 된 스택 포인터의 존재만으로 결과만 있던 답변에 이유가 생겼어요.
훨씬 논리적이고 입체적인 지식이 된거죠.
Optimizing Swift Performance
WWDC15의 Optimizing Swift Performance에서는 Whole Module Optimization의 진정한 가치를 알 수 있었어요.
이것도 WMO의 이름은 알고 있었어요 ㅋㅋ
WMO를 이용하면 Dynamic Dispatch를 Static Dispatch로 최적화할 수 있다.
딱 여기까지였습니다.
WMO가 뭘 해주길래 Dynamic Dispatch를 Static Dispatch로 바뀌는건가에 대해서는 제대로 생각하지 않았어요.
여기에도 굉장히 많은 과정이 있더라고요.
먼저, 컴파일러는 최대한 보수적으로 코드를 대해야 합니다.
a라는 클래스 인스턴스가 있을 때, a 클래스의 저장 프로퍼티인 name을 a.name이라고 호출한다고 해봐요.
컴파일러는 a의 name가 다른 서브 클래스에서 오버라이드 되었는지 알 수 없습니다.
그래서 오버라이드의 가능성을 고려해서 직접적으로 "A의 name"으로 호출할 수 없고, 간접적으로 name을 가져와야 합니다.
이런 문제가 발생하는 건 컴파일러가 정보가 부족해서 입니다.
A의 오버라이드에 대한 정보가 부족해서 직접적으로 호출을 못하는거에요.
WMO가 도입되기 전에는 파일마다 따로 따로 컴파일이 되기 때문에 컴파일러가 얻을 수 있는 정보는 파일 하나에만 제한되어 있었어요.
근데 WMO를 도입한 후 컴파일러는 전체 모듈로 정보의 범위가 훨씬 넓어진 거에요.
따라서 final이나 private를 이용해 "다른 곳"에서 오버라이드를 하지 않는다는 정보를 컴파일러에게 줄 수 있게 된거죠.
마무리
맨 처음에 나온 스택에서만 이런 큰 변화를 맞으니 멘붕이었습니다.
나는 왜 이렇게 좋은 걸 지금 봤지? 라는 생각이 계속 들었거든요.
그리고 재밌었어요. 지식의 빈 곳이 채워지면서 뭔지 모를 쾌감(?)이 느껴졌거든요.
사실... 이 지식을 프로젝트에 적용하려고 보면 아직은 머리가 깜깜해지긴 해요.
근데 이건 경험이 쌓이면 해결될 것이라는 것이 너무 명확했어요.
알고리즘도 처음엔 손도 못 대다가 경험이 쌓이면 점점 풀 수 있는 스펙트럼이 넓어지잖아요?
프로젝트도 뭐 그렇겠죠 ㅎ.ㅎ
항상 마무리가 엉성하긴 한데...
아무튼, WWDC 잘 들었다, 배운 것도 너무 많다, 여러분도 들어보세요 라는 말을 하고 싶었습니다.
특히 WWDC22는 한글 자막도 지원하니까요. (장단점이 있었습니다만...)
꼭 들어보세요!
(근데 일단 코테가 급하긴 한데... 이걸 듣는게 맞는가 싶기도 하고... 혼란스러운 취준생 마음...)
감사합니다.