引言:为什么对C++代码进行性能分析很重要?
C++是最快的编程语言之一,但即使使用它,你也可能写出慢速代码。开发者常常凭直觉花费数小时优化程序中并非关键的部分。性能分析是一种科学的优化方法:你测量程序在哪些地方花费了最多时间,然后有针对性地改进这些地方。
对于C++编程初学者来说,性能分析可能看起来很复杂,但实际上,基本工具一个晚上就能掌握。在本文中,我们将介绍三种流行的工具:gprof、perf和Valgrind,并学习如何解读它们的结果。
什么是性能分析?有哪些方法?
性能分析是在程序运行期间收集其行为数据的过程。主要有两种方法:
- 插桩式性能分析——在程序代码中添加特殊的“探针”(例如
gprof)。缺点:会减慢程序执行速度。 - 采样式性能分析——每隔固定时间间隔“窥视”程序,记录当前正在执行的函数(例如
perf)。几乎不降低程序速度。
还有用于查找内存泄漏(Valgrind)和缓存分析的工具。刚开始,掌握gprof和perf就足够了。
工具1:gprof——经典性能分析器
gprof是GCC内置的性能分析器。它分两步工作:数据收集和数据分析。
如何使用gprof
首先,使用-pg标志编译程序:
g++ -pg -o my_program my_program.cpp运行程序:
./my_program执行后,会生成一个gmon.out文件。现在运行gprof:
gprof my_program gmon.out > report.txt打开report.txt并查看表格:
Flat profile:Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 60.00 0.06 0.06 10000 0.01 0.01 slow_function 30.00 0.09 0.03 5000 0.01 0.02 medium_function 10.00 0.10 0.01 1 10.00 10.00 main在% time列中,显示了函数占用时间的百分比。在我们的示例中,slow_function是优化的主要候选对象。
提示:对于小型程序,gprof非常适用。对于大型项目,由于编译器优化,它可能提供不准确的数据。
工具2:perf——Linux上强大的采样器
perf是内置于Linux内核的性能分析器。它采用采样方法,几乎不降低程序速度。非常适合生产系统。
perf的基本用法
使用调试符号(-g标志)编译程序:
g++ -g -o my_program my_program.cpp启动性能分析:
perf record ./my_program程序运行结束后,查看报告:
perf report你会看到一个交互式界面。点击一个函数,可以查看哪些代码行执行得最频繁。输出示例:
Samples: 1K of event 'cycles'Event count (approx.): 250000000Overhead Command Shared Object Symbol 45.32% my_program my_program [.] slow_function 30.15% my_program my_program [.] medium_function 12.50% my_program libc-2.31.so [.] malloc 8.03% my_program my_program [.] main重要提示:perf需要root权限才能收集内核数据