[Go 공식문서 한국어 정리] ①50. Go 프로그램 프로파일링
Go 프로그램 프로파일링
https://go.dev/blog/pprof
Go의 프로파일링 도구를 사용하여 느린 프로그램을 분석하고 최적화하는 방법을 설명합니다. 실제 사례를 통해 11배 빠르게 만들고 메모리를 3.7배 줄인 경험을 공유합니다.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
① 서론
Robert Hundt의 논문에서 Go 프로그램이 C++보다 느렸던 사례를 바탕으로, Go의 pprof 도구를 사용해 병목 지점을 찾아 최적화했습니다. 핵심은 프로파일링 데이터를 기반으로 한 구체적인 개선입니다.
② 핵심 개념
1. CPU 프로파일: 1초에 약 100번 현재 실행 중인 함수를 샘플링합니다.
2. 메모리(힙) 프로파일: 약 524KB마다 1번 메모리 할당을 샘플링합니다.
3. go tool pprof: 프로파일 데이터를 분석하는 도구입니다.
4. net/http/pprof: HTTP 서버에 프로파일 엔드포인트를 추가합니다.
③ 주요 내용 상세
CPU 프로파일링 설정
import "runtime/pprof"
f, _ := os.Create("cpu.prof")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
$ go tool pprof 프로그램 cpu.prof
주요 pprof 명령
- topN: CPU 샘플 상위 N개 함수 (flat 기준)
- topN -cum: 누적(cumulative) 샘플 기준
- web: SVG 그래프로 프로파일 시각화
- list 함수명: 소스 코드 라인별 샘플 수
- disasm 함수명: 어셈블리 수준 분석
- web 함수명: 특정 함수 관련 샘플만 시각화
메모리 프로파일링
f, _ := os.Create("mem.prof")
pprof.WriteHeapProfile(f)
f.Close()
$ go tool pprof 프로그램 mem.prof
--inuse_objects 플래그로 할당 개수(크기 대신)를 확인할 수 있습니다.
최적화 사례
1. map[*BasicBlock]int → []int: 맵 조회를 슬라이스 인덱싱으로 변경
2. map[int]bool → []int: 중복 방지를 위해 appendUnique 함수 사용
3. 메모리 캐싱: FindLoops 호출 시 매번 할당하던 구조체를 전역 캐시로 재사용
최종 결과: 25.2초 → 2.29초(11배 향상), 메모리 1302MB → 360MB(3.7배 감소)
HTTP 프로파일링
import _ "net/http/pprof"
/debug/pprof/profile - 30초 CPU 프로파일
/debug/pprof/heap - 힙 프로파일
/debug/pprof/block - 고루틴 블로킹 프로파일
$ go tool pprof http://localhost:6060/debug/pprof/profile
④ 실전 활용
- go test -cpuprofile=cpu.out -memprofile=mem.out로 벤치마크 테스트 시 자동 프로파일링할 수 있습니다.
- 프로덕션 서버에 net/http/pprof를 임포트하여 실시간 프로파일링을 활성화하세요.
- top5 -cum으로 전체 호출 경로에서 병목을 파악합니다.
- list로 특정 함수의 어느 라인이 hotspot인지 확인합니다.
- 메모리 할당이 많은 코드는 가비지 컬렉션 부하를 일으키므로 객체 재사용이나 풀링을 고려하세요.
⑤ 정리
Go의 프로파일링 도구는 성능 문제를 객관적으로 진단하는 강력한 수단입니다. CPU 프로파일로 시간이 많이 소비되는 함수를 찾고, 메모리 프로파일로 할당 hotspot을 찾아 구조를 개선하면 큰 성능 향상을 얻을 수 있습니다. pprof의 시각화 기능을 활용하면 병목 지점을 직관적으로 파악할 수 있습니다.
#Go #Golang #pprof #프로파일링 #성능최적화 #CPU #메모리 #공식문서

오뉴노노 님의 최근 댓글
ㅋㅋㅋㅋㅋ 2019 01.14 잘 읽었습니다 2018 12.30 포인트가 없어서 아직 시작을 못하고있는데요! 글은 잘 읽었습니다! 포인트 쌓고 도전할거에요 2018 12.30