Go 1.26, 힙 할당 줄이고 스택 할당으로 성능 UP!

by DD
3개월 전
조회수 8

Go 1.25 및 1.26 버전에서 스택 할당(Stack Allocation)을 활용하여 힙(Heap) 할당으로 인한 성능 저하를 개선

컴파일러 최적화(Compiler Optimization)를 통해 개발자의 별도 코드 작성 없이 스택 할당을 자동화

작은 크기의 슬라이스(Slice)에 대한 스택 할당 지원으로 힙 할당 빈도 감소

C++/Rust 개발자들은 Go의 힙 기반 메모리 관리에 대해 언어 설계의 근본적인 차이(Fundamental Difference)를 지적

Go 1.25: 컴파일러 기반 스택 할당 자동화

Go 1.25에서는 컴파일러가 make() 함수를 통해 생성되는 슬라이스(Slice)의 크기가 작을 경우, 자동으로 스택에 메모리를 할당하는 최적화를 도입했다. 특히, `lengthGuess`가 작을 경우, 32바이트 이하의 슬라이스는 스택에 할당되어 힙 할당(Heap Allocation)을 피할 수 있다. 이는 개발자가 별도로 크기를 예측하거나 코드를 수정할 필요 없이 성능 향상을 얻을 수 있도록 한다.

Go 1.26: 힙으로 탈출하는 슬라이스 최적화

Go 1.26에서는 슬라이스가 함수에서 반환되어 힙으로 탈출하는 경우에도 스택 할당 최적화를 적용한다. 컴파일러는 `runtime.move2heap()` 함수를 사용하여 스택에 할당된 슬라이스를 힙으로 복사한다. 이로 인해, 슬라이스가 작을 경우 단 한 번의 힙 할당만 발생하며, 불필요한 메모리 할당(Unnecessary Memory Allocation)을 줄인다. 이는 개발자가 수동으로 코드를 최적화하는 것보다 효율적일 수 있다.

C++/Rust 개발자의 시각: 언어 설계의 차이

댓글에서는 C++/Rust 개발자들이 Go의 힙 기반 메모리 관리에 대해 비판적인 시각을 제시한다. C++ 및 Rust는 스택 할당을 기본으로 하며, 힙 할당은 명시적으로 이루어진다. 반면, Go는 힙 할당이 기본이므로, 스택 할당을 위한 추가적인 최적화가 필요하다는 점을 지적한다. 이는 언어 설계 철학의 차이에서 기인하며, Go가 메모리 관리(Memory Management) 측면에서 다른 접근 방식을 취하고 있음을 보여준다.

성능 개선을 위한 개발자의 역할

Go 컴파일러의 자동화된 스택 할당 최적화는 개발자의 노력을 줄여주지만, 여전히 슬라이스 크기 예측(Slice Size Estimation)과 같은 수동 최적화가 유효하다. 특히, 슬라이스 크기를 정확하게 예측할 수 있는 경우, `make()` 함수를 사용하여 초기 용량을 지정함으로써 추가적인 힙 할당을 방지할 수 있다. 하지만, 컴파일러 최적화를 통해 대부분의 경우 개발자가 직접 코드를 수정하지 않아도 성능 향상을 얻을 수 있다.

Allocating on the Stack (go)