Performance profiling
The recipe section of the documentation focuses on the objectives with minimal explanations about the basics.
Objective
I want to profile sbt to understand what it spent time on.
Solution: traces
- Shutdown an existing server if any:
sbt shutdown - Run a command with
--server --traces
$ sbt --server --traces compile
....
$ ls target/traces/build.trace
target/traces/build.trace
This produces a Chrome tracing file target/traces/build.trace,
which can be viewed using Perfetto,
shows how long each task took.
Solution: timings
- Shutdown an existing server if any:
sbt shutdown - Run a command with
--server --timings
$ sbt --server --timings compile
....
Total time: 4116 ms
aaa-build / Compile / compileIncremental : 731 ms
....
This outputs task timing information on the terminal.
Solution: flame graph
Install async-profiler
by putting asprof and jfrconv on your PATH:
$ ln -s $HOME/Applications/async-profiler-4.2/bin/asprof $HOME/bin/asprof
$ ln -s $HOME/Applications/async-profiler-4.2/bin/jfrconv $HOME/bin/jfrconv
-
Close anything that may affect the profiling, and run sbt in one terminal
-
In another terminal run
jpsto identify the process ID of sbt$ jps 92746 sbt-launch.jar 92780 Jps -
Run
asprofwith the duration flag.-d 60means 60s:$ asprof -d 60 -f /tmp/flamegraph.jfr <process id>This produces a JFR (Java Flight Recorder) file.
-
Run
jfrconvas follows to convert the*.jfrfile to a flame graph:$ jfrconv --lines /tmp/flamegraph.jfr /tmp/flamegraph.html
Alternative: JVM profiling
You can use a profiler like VisualVM to identify implementation-level timings.
- Shutdown all existing servers if any:
sbt shutdownall - Start an sbt session with
--server - Launch VisualVM, and double-click on
xsbt.boot.Boot - Go to Sampler tab, and click CPU
- Run a command inside the sbt shell
- Click on the Stop button in Sampler tab
The threads named pool-n-thread-m are the task threads.