Profiling

In this section you can find some tips on how to profile your Scala Native binary in Linux.

Scala Native binaries are regular executables. Tools that works with native executables will work with Scala Native executables. That includes the Linux perf performance analysis tool.

Measuring execution time and memory

  • With the time command you can measure execution time:

time ./target/scala-2.13/scala-native-out
real  0m0,718s
user  0m0,419s
sys   0m0,299s
  • With the /usr/bin/time --verbose command you can also see memory consumption:

/usr/bin/time --verbose ./target/scala-2.13/scala-native-out
Command being timed: "./target/scala-2.13/scala-native-out"
User time (seconds): 0.49
System time (seconds): 0.23
Percent of CPU this job got: 99%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.72
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 1317184
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 328341
Voluntary context switches: 1
Involuntary context switches: 70
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0

Creating Flamegraphs

A flamegraph is a visualization of the most frequent code-paths of a program. You can use flamegraphs to see where your program spends most of its CPU time.

Use samply

samply is a command line CPU profiler which uses the Firefox profiler as its UI. Samply has support for de-mangling Scala Native symbols.

Use hotspot

hotspot is a GUI for perf which provides a flamegraph view. As of this writing, hotspot does not de-mangle Scala Native symbols.

Using using perf and FlameGraph

Follow these steps:

  • You need to install the perf command if you haven’t got it already:

sudo apt update && sudo apt install linux-tools-generic
  • Then clone the flamegraph repository into e.g. ~/git/hub/

cd ~ && mkdir -p git/hub && cd git/hub/
git clone git@github.com:brendangregg/FlameGraph.git
  • Then navigate to your Scala Native project and, after building your binary, you can create a flamegraph like so:

sudo perf record -F 1000 -a -g ./target/scala-2.13/scala-native-out
sudo perf script > out.perf
~/git/hub/FlameGraph/stackcollapse-perf.pl out.perf > out.folded
~/git/hub/FlameGraph/flamegraph.pl out.folded > kernel.svg
  • Open the file kernel.svg in your browser and you can zoom in the interactive SVG-file by clicking on the colored boxes as explained here. A box represents a stack frame. The broader a box is the more CPU cycles have been spent. The higher the box is, the deeper in the call-chain it is.

  • The perf option -F 1000 means that the sampling frequency is set to 1000 Hz. You can experiment with changing this option to get the right accuracy; start with e.g. -F 99 and see what you get. You can then increase the sampling frequency to see if more details adds interesting information.

Continue to runtime.