Quick Flow
go test -run=^$ -bench=. -benchmem ./...
go test -run=^$ -bench=BenchmarkEncode -cpuprofile cpu.out
go tool pprof -http=:0 cpu.outGo 성능 점검은 같은 입력·환경에서 benchmark로 변화를 재현하고, pprof로 실제 비용 위치를 좁히는 흐름입니다. normal test를 빼고 benchmark만 볼 때는 `-run=^Go 성능 점검은 같은 입력·환경에서 benchmark로 변화를 재현하고, pprof로 실제 비용 위치를 좁히는 흐름입니다. normal test를 빼고 benchmark만 볼 때는 를 함께 둡니다.
벤치마크
함수 이름은 BenchmarkXxx 형태다
func BenchmarkEncode(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := Encode(sample); err != nil {
b.Fatal(err)
}
}
}benchmark는 testing.B를 받고, 반복 횟수는 Go 테스트 러너가 b.N으로 조절합니다.
Go 1.24 이상에서는 timer와 setup 경계를 더 명확히 하는 b.Loop도 쓸 수 있습니다.
func BenchmarkEncodeLoop(b *testing.B) {
for b.Loop() {
if _, err := Encode(sample); err != nil {
b.Fatal(err)
}
}
}b.Loop은 처음 시작할 때 timer를 reset하고 끝나면 멈춥니다. 한 benchmark에서는 b.Loop와 for i := 0; i < b.N; i++ 중 하나만 씁니다. Go 1.23 이하를 지원하면 기존 b.N loop를 유지합니다.
할당까지 보려면 -benchmem을 붙인다
go test -bench=. -benchmem ./internal/encoder실행 시간만 보면 놓치는 문제가 있습니다. -benchmem은 operation당 할당 횟수와 바이트를 같이 보여 줍니다.
준비 비용은 측정에서 빼야 한다
func BenchmarkParse(b *testing.B) {
data := loadFixture()
b.ResetTimer()
for i := 0; i < b.N; i++ {
if _, err := Parse(data); err != nil {
b.Fatal(err)
}
}
}fixture 로딩이나 테스트 데이터 생성이 측정 대상이 아니면 b.ResetTimer() 이후부터 재는 편이 정확합니다. 반복 안의 error를 무시하면 실패한 작업의 숫자를 재게 되므로 b.Fatal로 중단합니다. 분기별 입력이 필요하면 b.Run으로 이름을 나누고, 비교 전후에는 같은 -count, -benchtime, CPU 부하 조건을 유지합니다.
프로파일
CPU profile은 병목 함수를 찾는다
go test -run=^$ -bench=BenchmarkEncode -cpuprofile cpu.out
go tool pprof -http=:0 cpu.outpprof에서는 top, list, web 같은 명령으로 시간이 많이 쓰인 함수를 봅니다. -http=:0는 임시 웹 UI를 열어 호출 그래프를 볼 수 있습니다. CPU profile은 실행 중 CPU를 쓴 위치이고, heap profile은 메모리 사용 상태를 보는 자료이므로 같은 질문에 섞어 해석하지 않습니다.
go test -run=^$ -bench=BenchmarkEncode -memprofile mem.out
go tool pprof -http=:0 mem.outHTTP 서버는 net/http/pprof를 붙일 수 있다
import _ "net/http/pprof"
go func() {
_ = http.ListenAndServe("localhost:6060", nil)
}()blank import는 pprof handler를 DefaultServeMux에 등록하고, ListenAndServe(..., nil)은 그 mux를 사용합니다. 운영 서버에 붙일 때는 노출 범위와 default mux 공유 여부를 확인합니다. profiling endpoint는 내부망, 인증, 임시 진단 환경처럼 접근 통제를 전제로 둡니다.
선택 기준
| 상황 | 먼저 떠올릴 선택 |
|---|---|
| 함수 성능 비교 | go test -bench |
| 할당 확인 | -benchmem |
| CPU 병목 추적 | -cpuprofile + go tool pprof |
| 메모리 사용 추적 | heap profile |
| 서버 런타임 진단 | net/http/pprof |
주의할 점
benchmark 결과는 실행 환경, 입력 데이터, compiler 최적화, 병렬 실행 여부에 영향을 받습니다. 한 번의 숫자보다 같은 조건에서 여러 번 측정한 변화량을 봐야 합니다. profile은 먼저 재현 가능한 benchmark나 실제 부하에서 얻고, net/http/pprof를 외부에 그대로 노출해 민감한 런타임 정보가 새지 않게 합니다.
참고 링크
3 sources