이제는 거울 앞에 선 꼰대 C프로그래머들을 보라. 함수의 리턴으로 구조체 값을 쓰는 것은 생각해 본 적도 없다.
어.. 그거 구조체가 스택에 생성되는데 그거 바로 리턴하면 스택 뿌서지면서 휘발되지 않아? 아참 아니지.. 안 써봐서 그렇지 구조체를 리턴하면 값을 리턴하는 결과가 되면서 스택을 복사해가는 거지.. 아 그렇지 아규먼트와 리턴 값은 스택을 통해서 이뤄지는 것이니 구조체도 그렇지. 찾아보니 온전히 잘 된다는 것 같다. 아니 구조체를 리턴해 본 적이 없다니까? 포인터만 리턴해봤지.
그리하여 go의 경우를 실험해봤다. 얘는 GC 해주고 뭐 알아서 해주는 것이 많으니 함수 내에 선언한 구조체 변수의 포인터를 리턴하면 빠르지 않을까? 즉, 상상도는 이렇다.
실험하고 찾아보니 4번 항목은 그런 것이었던 것이다.. 스택에 잡아둔 구조체를 날려먹지 않기 위해서 go가 힙에서 메모리를 가져오고 거기에 복사하고 그 주소를 포인터로 리턴한다는 것. 즉, 지지고 볶고 구간이 들어간다. 실제로는 훨씬 더 지지고 볶는다.
그냥 값으로 리턴하면 어떨까? 복사는 매한가지이지만 스택에서 복사하고 땡이다. 힙 할당 과정이 필요없는 것. 위에 썼지만 스택 할당이라는 것은 그냥 크기 만큼 오프셋 이동하는게 전부임.
이미 자세히 실험한 사람이 있다.
https://philpearl.github.io/post/bad_go_pointer_returns/
왐마.. 포인터 리턴한다고 뭔 일을 저리 많이 하는 겨..
결론 1 : 구조체도 그냥 값으로 리턴 하는 것이 빠름.
결론 2 : 데이터 lifetime이 짧으면 더욱 그러함. (즉각적으로 GC가 개입하므로 그렇다는 듯?)
그렇다면 이미 할당된 버퍼를 함수에 포인터로 넘겨주면 어떨까? 그게 젤 좋다. 그런데 go에서는 포인터 변수에 인덱싱도 덧셈 뺄셈도 안 되니 영..뭐 할 수 있는 것을 잘 모르겠다... 찬찬히 공부해 보는 것으로..
전설의 임인건님 책을 읽고 포인터의 뺄셈은 의미없다고 알고 있는 분들이 있는데 안 그렇습니다. 포인터를 빼서 엉망진창 쓰까진 자료형의 타입을 추론하거나 두 포인터 사이에 아이템이 몇 개인가 계산 할 수도 있고 그래요..