L34 — Profiling với pprof

Ba module để "chạm" vào pprof: đọc flamegraph trực quan, phân tích bảng top10, và đi qua một hành trình tối ưu endpoint từ 200ms xuống 50ms qua 5 bước. Mỗi module standalone — mở file:// chạy được.

1. Flamegraph reader — width = thời gian

Flamegraph dưới mô phỏng CPU profile của 1 HTTP endpoint chạy 10 giây. Click vào bất kỳ block để xem flat (time trực tiếp), cum (gồm callees), % tổng, và diagnosis ngắn. Block rộng nhất ở leaf chính là bottleneck cần fix đầu tiên.

main.main (10.0s, 100%) http.ServeHTTP (9.5s, 95%) api.HandleSearch (9.5s, 95%) regexp.doMatch (6.0s, 60%) ★ BOTTLENECK json.Marshal (2.0s, 20%) db.Query (1.5s, 15%) memmove (1.2s) regexp.machine.match (4.2s, 42%) ★ HOT LEAF mallocgc (0.8s) syscall.read (1.4s) ↑ Stack growth: trên = caller, dưới = callee. Width = thời gian. Wide leaf đỏ = bottleneck.
Chọn 1 block để xem chi tiết.

2. pprof top10 simulator — flat vs cum

Bảng dưới là output top10 của cùng profile ở Module 1. Click vào header flat hoặc cum để sort. Row đỏ là hot leaf (flat cao và ≈ cum) — đây là chỗ tốn CPU thật sự, optimize trực tiếp được. Row có cum cao nhưng flat thấp là entry point — phải đi xuống callees để tối ưu.

flat (s) flat bar flat% cum (s) cum bar cum% function
Cách đọc:
  • flat = time TRỰC TIẾP trong function (không tính callees). Cao → là leaf nóng.
  • cum = time trong function + tất cả callees. Cao → là entry point của hot path.
  • flat ≈ cum → leaf thật sự, tự thân tốn time → fix tại đây.
  • flat << cum → caller, time tiêu ở callees → đi xuống tree để tìm fix.

3. Optimization journey — từ 200ms → 50ms qua 5 bước

Kéo slider để đi qua 5 bước optimize một endpoint /api/search. Mỗi bước fix 1 bottleneck cụ thể; bảng bên trái show profile trước fix, bên phải sau fix, và banner dưới hiển thị speedup tích lũy. Đây là workflow chuẩn mọi optimizer Go nên quen.

Step 0

Trước fix

200 ms avg latency
QPS: 500

Sau fix

200 ms avg latency
QPS: 500
1.0× Bắt đầu — chưa fix gì.
// Kéo slider để xem fix.