So, you wrote an R package containing C++ (or other compiled code) and you want to profile it? Great! Profiling code can help you find bottlenecks in your code that you can look at more closely for further optimization.
I work on Pop!_os, a free Ubuntu based operating system. I am writing this guide to document the steps I took in order to get profiling working for me. There are a few slight differences between what I had to do and what I found online so I hope this is useful.
I listed all the references I used at the bottom of this document.
On my Ubuntu-based system, installing gperftools was as simple as using the package manager:
sudo apt-get install google-perftools
If you don’t have
graphviz which makes pretty graphs of call traces, you can install that the same way.
Next you need to install
pprof which depends on the programming language Go.
sudo apt-get install golang-go go get github.com/google/pprof
Congratulations, you are now closer to your goal. Now we just need to set some environment variables.
First, it is critical that we can find where the shared object library from
perftools is. On most Linux based systems, it seems that it lives in
/usr/lib/libprofiler.so. Apparently that’s not the case for Pop!_os. You can use
find to figure out where it lives on your machine:
sudo find / -name libprofiler.so
Wherever it is, you now need to make an environment variable with that path:
Next you need to find where the R binary is. This is used by the profiler to resolve symbols into names of compiled functions used by R. Normally it seems it is located at
/usr/lib/R/bin/exec/R. In my case, using this location and firing up the profiler gave me a somewhat frightening error:
cannot find system Renviron Fatal error: unable to open the base package
In my case the binary was actually located at
/usr/lib/R, so the following worked on my machine:
You can find it from within R by calling
Now you’re all ready to go. Assuming you are in a directory containing a R script which calls code you want profilied, say
test.R, then you can call:
CPUPROFILE="myprof.log" /usr/lib/R/bin/exec/R -f test.R
CPUPROFILE="myprof.log" will create a file
myprof.log in the current working directory. You can name it whatever you prefer.
After running your script, it should print normally to the console, but with some line like the following at the end
PROFILE: interrupts/evictions/bytes = 3407/1019/588344.
To see the results in text format, use
google-pprof --text /usr/lib/R/bin/exec/R myprof.log | more
To see a graph, just use the
google-pprof -web /usr/lib/R/bin/exec/R myprof.log
You will see something like the following: