Golang 실전 가이드

Golang의 핵심 개념과 실무 활용

Go중급
6시간
3개 항목
학습 진행률0 / 3 (0%)

학습 항목

1. Go
초급
Golang|성능|최적화|가이드
퀴즈튜토리얼
2. Go
중급
Golang|핵심|개념|완벽|정리
퀴즈튜토리얼
3. TypeScript
고급
Golang|최신|기능|완벽|가이드
퀴즈튜토리얼
1 / 3

이미지 로딩 중...

Golang 성능 최적화 가이드 - 슬라이드 1/11

Golang 성능 최적화 가이드

Go 언어의 성능을 극대화하기 위한 핵심 기법들을 소개합니다. 메모리 관리, 동시성 처리, 프로파일링 등 실무에서 바로 적용 가능한 최적화 기법을 배울 수 있습니다.


카테고리:Go
언어:Go
난이도:beginner
메인 태그:#Go
서브 태그:
#Performance#Concurrency#MemoryOptimization#Profiling

들어가며

이 글에서는 Golang 성능 최적화 가이드에 대해 상세히 알아보겠습니다. 총 10가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. 슬라이스_사전할당
  2. 문자열_연결_최적화
  3. 고루틴_풀_패턴
  4. 포인터_vs_값_전달
  5. 맵_사전할당
  6. sync.Pool_재사용
  7. 버퍼_채널_활용
  8. pprof_프로파일링
  9. 인라인_함수_최적화
  10. 불필요한_인터페이스_회피

1. 슬라이스_사전할당

개요

슬라이스의 크기를 미리 할당하여 불필요한 메모리 재할당을 방지하고 성능을 향상시킵니다.

코드 예제

// 비효율적
data := []int{}
for i := 0; i < 1000; i++ {
    data = append(data, i)
}

// 효율적
data := make([]int, 0, 1000)
for i := 0; i < 1000; i++ {
    data = append(data, i)
}

설명

make 함수로 용량을 미리 지정하면 append 시 메모리 재할당이 발생하지 않아 약 2-3배 빠릅니다.


2. 문자열_연결_최적화

개요

여러 문자열을 연결할 때 strings.Builder를 사용하면 메모리 효율이 크게 향상됩니다.

코드 예제

import "strings"

// 비효율적
result := ""
for i := 0; i < 100; i++ {
    result += "text"
}

// 효율적
var builder strings.Builder
for i := 0; i < 100; i++ {
    builder.WriteString("text")
}
result := builder.String()

설명

Builder는 내부 버퍼를 재사용하여 + 연산자보다 10배 이상 빠르고 메모리 할당도 적습니다.


3. 고루틴_풀_패턴

개요

무제한 고루틴 생성 대신 워커 풀을 사용하여 리소스를 효율적으로 관리합니다.

코드 예제

func workerPool(jobs <-chan int, results chan<- int) {
    for i := 0; i < 5; i++ {
        go func() {
            for job := range jobs {
                results <- job * 2
            }
        }()
    }
}

jobs := make(chan int, 100)
results := make(chan int, 100)
workerPool(jobs, results)

설명

고루틴 개수를 제한하여 과도한 컨텍스트 스위칭을 방지하고 메모리 사용량을 안정적으로 유지합니다.


4. 포인터_vs_값_전달

개요

큰 구조체는 포인터로 전달하여 복사 오버헤드를 줄이고 성능을 개선합니다.

코드 예제

type LargeStruct struct {
    data [1000]int
}

// 비효율적 (값 복사)
func process(s LargeStruct) {
    // 처리 로직
}

// 효율적 (포인터)
func process(s *LargeStruct) {
    // 처리 로직
}

설명

구조체가 클수록 포인터 전달이 유리하며, 작은 구조체는 값 전달이 캐시 효율성 면에서 더 나을 수 있습니다.


5. 맵_사전할당

개요

맵의 예상 크기를 미리 지정하여 동적 확장으로 인한 성능 저하를 방지합니다.

코드 예제

// 비효율적
m := make(map[string]int)
for i := 0; i < 1000; i++ {
    m[fmt.Sprintf("key%d", i)] = i
}

// 효율적
m := make(map[string]int, 1000)
for i := 0; i < 1000; i++ {
    m[fmt.Sprintf("key%d", i)] = i
}

설명

맵 크기를 사전에 지정하면 해시 테이블 재할당 횟수가 줄어 성능이 향상됩니다.


6. sync.Pool_재사용

개요

자주 생성/삭제되는 객체를 sync.Pool로 재사용하여 GC 부담을 줄입니다.

코드 예제

var bufferPool = sync.Pool{
    New: func() interface{} {
        return new(bytes.Buffer)
    },
}

buf := bufferPool.Get().(*bytes.Buffer)
buf.Reset()
defer bufferPool.Put(buf)

buf.WriteString("temporary data")

설명

Pool을 사용하면 객체 생성 비용과 가비지 컬렉션 압력을 대폭 줄일 수 있습니다.


7. 버퍼_채널_활용

개요

버퍼를 가진 채널을 사용하여 송수신 블로킹을 줄이고 처리량을 높입니다.

코드 예제

// 버퍼 없음 (블로킹 가능)
ch := make(chan int)

// 버퍼 있음 (논블로킹)
ch := make(chan int, 100)

go func() {
    for i := 0; i < 100; i++ {
        ch <- i  // 버퍼 범위 내 블로킹 없음
    }
}()

설명

적절한 버퍼 크기는 고루틴 간 통신 대기 시간을 줄여 전체 처리 속도를 향상시킵니다.


8. pprof_프로파일링

개요

pprof를 사용하여 CPU와 메모리 사용을 분석하고 병목 지점을 찾습니다.

코드 예제

import _ "net/http/pprof"
import "net/http"

func main() {
    go func() {
        http.ListenAndServe("localhost:6060", nil)
    }()

    // 애플리케이션 코드
}

// 터미널: go tool pprof http://localhost:6060/debug/pprof/profile

설명

브라우저나 CLI로 실시간 프로파일링 데이터를 확인하여 최적화가 필요한 부분을 정확히 파악할 수 있습니다.


9. 인라인_함수_최적화

개요

작은 함수는 컴파일러가 자동으로 인라인화하여 함수 호출 오버헤드를 제거합니다.

코드 예제

// 인라인 가능 (작고 단순)
func add(a, b int) int {
    return a + b
}

// 인라인 불가능 (복잡)
func complexCalc(data []int) int {
    sum := 0
    for _, v := range data {
        sum += v * v
    }
    return sum
}

설명

간단한 함수는 인라인화되어 성능이 향상되며, go build -gcflags="-m" 명령으로 확인할 수 있습니다.


10. 불필요한_인터페이스_회피

개요

성능이 중요한 부분에서는 구체 타입을 사용하여 동적 디스패치 비용을 줄입니다.

코드 예제

// 느림 (인터페이스)
func process(r io.Reader) {
    // 가상 메서드 호출
}

// 빠름 (구체 타입)
func process(f *os.File) {
    // 직접 메서드 호출
}

설명

인터페이스는 유연성을 제공하지만 간접 호출 비용이 있으므로, 핫패스에서는 구체 타입 사용을 고려하세요.


마치며

이번 글에서는 Golang 성능 최적화 가이드에 대해 알아보았습니다. 총 10가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#Go #Performance #Concurrency #MemoryOptimization #Profiling

#Go#Performance#Concurrency#MemoryOptimization#Profiling