C++ Profiling on Linux: A Guide for Those Who Want to Speed Up Code

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Is your C++ code running slow? Time to look under the hood

\n\n

You've written what seems like perfect C++ code. Compilation went smoothly, the program starts... but it runs kind of sluggishly. Sound familiar? You're tempted to rewrite everything in assembly or urgently add multithreading. Don't rush. Most likely, the problem isn't the architecture, but a couple of "hot" functions that are consuming 90% of the CPU time.

\n\n

In the Linux world, we have a powerful arsenal of tools for profiling C++ code. This isn't magic, it's science. We don't guess, we measure. In this guide, I'll show you four practical approaches: from a quick "bird's-eye view" to micro-benchmarking. You'll learn how to profile C++ on Linux like a true pro.

\n\n

Why guesswork is evil, and profiling is good

\n\n

Before diving into the code, remember the golden rule of optimization: "Don't optimize what isn't measured". Your intuition is a poor advisor. We often spend hours optimizing a function that's called once a minute, while ignoring a trivial loop of 10 million iterations.

\n\n

Profiling provides answers to three main questions:

\n
    \n
  • Where does the program spend the most time?
  • \n
  • Why is this happening (inefficient algorithm, many I/O operations, cache misses)?
  • \n
  • What changed after your edits?
  • \n
\n\n

Today, we'll cover four tools that will handle 99% of your tasks. Let's go!

\n\n

Tool #1: gprof — a classic

\n\n

gprof is the old, reliable, built-in GNU profiler. It works in two stages: collecting statistics during program execution and analyzing them. Pros: no need to install anything extra, it's available in every distribution. Cons: gives approximate results and doesn't work with multithreaded programs out of the box.

\n\n

How to use gprof

\n\n

Step 1. Compile the program with the special -pg flag:

\n
g++ -pg -O2 my_program.cpp -o my_program
\n\n

Note: we use -O2. Profiling a debug build without optimizations is pointless — you'll get a distorted picture.

\n\n

Step 2. Run the program. It will run slightly slower because gprof is collecting data.

\n
./my_program
\n\n

Step 3. A file named gmon.out will appear in the current directory. Analyze it:

\n
gprof my_program gmon.out > analysis.txt
\n\n

Open analysis.txt and you'll see something like:

\n
Flat profile:\nEach sample counts as 0.01 seconds.\n  %   cumulative   self              self     total\n time   seconds   seconds    calls  us/call  us/call  name\n 60.00      0.06     0.06    10000     6.00     6.00  slow_function\n 20.00      0.08     0.02     5000     4.00     4.00  fast_function\n 10.00      0.09     0.01                             main
\n\n

Voila! We can see that slow_function took 60% of the time. This is our candidate for optimization.

\n\n

Example code for profiling

\n\n

Let's write a simple program that we'll profile with all the tools:

\n\n
#include <iostream>\n#include <cmath>\n\nvoid slow_function(int n) {\n    volatile double sum = 0.0; // volatile, so the compiler doesn't optimize it to zero\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < 1000; ++j) {\n            sum += std::sin(i) * std::cos(j);\n        }\n    }\n    std::cout << sum << std::endl;\n}\n\nvoid fast_function(int n) {\n    volatile int count = 0;\n    for (int i = 0; i < n; ++i) {\n        count += i % 2;\n    }\n    std::cout << count << std::endl;\n}\n\nint main() {\n    slow_function(10000);\n    fast_function(50000);\n    return 0;\n}
\n\n

Compile it with the -pg flag and run

Blogs

Book Recommendations