Profile Stack Aggregator (Go)
Topics: profiling, pprof data model, flat vs cumulative
Problem
A CPU profiler captures stack samples: every few milliseconds it records the call stack and how
often that exact stack was seen. To turn a pile of samples into a profile, you aggregate them into
flat and cumulative time per function — exactly what go tool pprof shows.
type Sample struct { Stack []string; Count int } // Stack is root -> leaf
type Stats struct { Flat, Cumulative map[string]int }
func Aggregate(samples []Sample) Stats
func (s Stats) Hottest() string
- Flat: a function's flat count is the number of samples in which it was the leaf (the last
frame — the function actually on-CPU).
- Cumulative: a function's cumulative count is the number of samples in which it appears
anywhere in the stack. If a function appears multiple times in one stack (recursion), count it
once per sample, not once per frame.
- Samples with an empty stack or a non-positive count contribute nothing. Both maps are
always non-nil.
Hottest returns the function with the largest flat count, ties broken by the
lexicographically smallest name; "" when there are no flat counts.
[main handler parse]×3, [main handler encode]×2, [main handler]×1
flat: parse 3, encode 2, handler 1
cum: main 6, handler 6, parse 3, encode 2
hottest: parse
One pass over the samples does it: add Count to the leaf's flat tally, and to each distinct
frame's cumulative tally (a per-sample seen set handles recursion). Hottest needs an explicit
tie-break since Go map iteration order is randomized.
Sign in to submit your solution.