Rust · from scratch · a call tree you can read
Stopwatch is a profiler. It measures the time inside every function, separates a function's own work from time spent in its children, and blooms the whole run into a chronomandala. Pick a workload and watch the time unfold.
Timing is usually the flaky part of a profiler, because wall-clock noise makes small runs unrepeatable. Stopwatch injects the clock. The Rust binary reads the system clock, and the demo above uses a clock that counts units of work, so the bloom is exactly reproducible. Everything else is identical.
Every span records the time on the way in and on the way out. Spans nest, so the profiler always knows which function is running and who called it.
Total time is everything between enter and exit. Self time subtracts the time spent inside children, so a function that only calls others shows almost no self time. That difference is the whole game.
Each function becomes an arc. Its sweep is its share of total time, its ring is its call depth, and its color runs from cold blue (waiting on children) to hot orange (its own work). Hot leaves glow.
// self time is computed per activation, never guessed fn exit(&mut self) { let elapsed = self.clock.now_nanos() - frame.start; node.total_nanos += elapsed; node.self_nanos += elapsed - frame.children_nanos; parent.children_nanos += elapsed; }
The CLI runs real workloads under the system clock and prints an indented call tree with total time, self time, and percent, then names the line where the program spent most of its life.
cargo run -- run --workload sort
cargo run -- run --workload mixed --json # the same tree the bloom reads