There is a limit to how much you can optimize large pieces of code (like frameworks) through manual code analysis. While finding redundant loops, optimizing algorithms, using bitwise operators are relatively easier, it is almost impossible to detect which parts actually take up the maximum CPU time through observation. Callgrind can do that for you. While there are many other tools available, Callgrind is my favourite because it has minimum external dependencies, does not need a GUI (though an optional GUI is available) and it is very easy to run without modifying your existing code. As it is a tool that comes with the popular memory leak-checker Valgrind, it supports the same programming languages like C, C++, Java, Perl, Ptython, Assembly and many more.
I will show how to create a portable Valgrind package which you can use anywhere as long as the platform architecture matches your compilation. Here are the simple steps to test-drive Callgrind on one of your programs:
- Download the source code from here. Available in repository by default on many distros but we want to make it portable.
- Extract and compile Valgrind using:
$ ./configure --prefix=/target/directory/for/package/creation/valgrind $ make
- Once the compilation is over, you have Valgrind ready at
- Export the path to the Valgrind binaries
$ export PATH=/target/directory/for/package/creation/valgrind/bin:$PATH
- Run your program with Callgrind (just as you normally do) to profile it:
$ valgrind --tool=callgrind ./myprogram option1 option2
- Check the PID of the process using:
$ ps ax|grep valgrind
- The profiler output file will be generated in the current directory. The name should be callgrind.out.PID (the same PID from the previous step).
- To make it understandable and sort the functions in descending order by CPU usage time, run:
$ callgrind_annotate callgrind.out.PID //callgrind_annotate needs Perl
- By default callgrind_annotate prints everything in the terminal. Redirect everything to a file if you want to check it later:
$ callgrind_annotate callgrind.out.PID > callgrind.profile
That’s simple enough! Now you have a portable Callgrind to profile your programs with.
Another heap profiler: Heaptrack