Introduction: Why is it important to profile C++ code?
\nC++ is one of the fastest programming languages, but even in it you can write slow code. Developers often spend hours optimizing the wrong parts of a program based on intuition. Profiling is a scientific approach to optimization: you measure where the program spends the most time and purposefully improve those areas.
\nFor beginner C++ programmers, profiling may seem complex, but basic tools can be mastered in one evening. In this article, we will cover three popular tools: gprof, perf, and Valgrind, and learn how to interpret their results.
What is profiling and what methods exist?
\nProfiling is the collection of data about a program's operation during its execution. There are two main approaches:
\n- \n
- Instrumenting profiling — special "probes" are added to the program code (e.g.,
gprof). Downside: it slows down program execution. \n - Sampling profiling — at regular intervals, it "peeks" into the program and records which function is currently executing (e.g.,
perf). It barely slows down the program. \n
There are also tools for finding memory leaks (Valgrind) and cache analysis. To start, it's enough to master gprof and perf.
Tool 1: gprof — the classic profiler
\ngprof is a built-in profiler for GCC. It works in two stages: data collection and analysis.
How to use gprof
\nFirst, compile the program with the -pg flag:
g++ -pg -o my_program my_program.cpp\nRun the program:
\n./my_program\nAfter execution, a file called gmon.out will appear. Now run gprof:
gprof my_program gmon.out > report.txt\nOpen report.txt and look at the table:
Flat profile:\nEach sample counts as 0.01 seconds.\n % cumulative self self total\n time seconds seconds calls ms/call ms/call name\n 60.00 0.06 0.06 10000 0.01 0.01 slow_function\n 30.00 0.09 0.03 5000 0.01 0.02 medium_function\n 10.00 0.10 0.01 1 10.00 10.00 main\nThe % time column shows what percentage of time the function took. In our example, slow_function is the main candidate for optimization.
Tip: For small programs, gprof works great. For large projects, it can give inaccurate data due to compiler optimizations.
Tool 2: perf — a powerful sampler for Linux
\nperf is a profiler built into the Linux kernel. It works using the sampling method and barely slows down the program. It is ideal for production systems.
Basic usage of perf
\nCompile the program with debug symbols (the -g flag):
g++ -g -o my_program my_program.cpp\nStart profiling:
\nperf record ./my_program\nAfter the program finishes, view the report:
\nperf report\nYou will see an interactive interface. By clicking on a function, you can see which lines of code were executed most often. Example output:
\nSamples: 1K of event 'cycles'\nEvent count (approx.): 250000000\nOverhead Command Shared Object Symbol\n 45.32% my_program my_program [.] slow_function\n 30.15% my_program my_program [.] medium_function\n 12.50% my_program libc-2.31.so [.] malloc\n 8.03% my_program my_program [.] main\nImportant: perf requires root privileges to collect kernel