当前位置: 首页 > article >正文

Linux编程中的性能优化方法和工具

0、序

在面试过程中,经常会被提及的一个问题就是,性能优化的方法和工具。对于这个问题,笔者一开始的理解是比较狭隘的,以为只有perf之类的性能分析工具才是答案,然而这类工具使用的确不多,因此每每回答这种问题,都会老实巴交的说不太了解。

直到现在才醒悟过来,编码中的一些看似顺其自然的选择其实就是性能优化的一种方法,比如数据结构的合理选择,比如内联函数的使用...

现学习总结如下。

1、方法

1) 选择合适的算法和数据结构

  • 算法复杂度分析:在解决问题之前,对不同的算法进行时间复杂度和空间复杂度分析,选择复杂度最低的算法。如在排序时,对于大规模数据,快速排序通常比冒泡排序效率高得多。

  • 数据结构优化:根据实际应用场景选择合适的数据结构。例如,在频繁进行插入和删除操作的场景中,使用链表可能比数组更高效;而在需要快速随机访问元素的情况下,数组则更合适。

2) 优化代码实现

  • 减少不必要的计算:避免在循环中进行重复的计算,可将循环不变式的计算提到循环外面。

  • 优化循环结构:尽量减少循环的嵌套层数,因为多层嵌套循环会使时间复杂度呈指数增长。同时,在循环中要避免使用复杂的函数调用,可将函数调用的结果保存起来,避免多次调用。

  • 合理使用内联函数:对于短小且频繁调用的函数,可使用内联函数,以减少函数调用的开销。但内联函数不宜过长,否则会导致代码膨胀。

3) 内存管理优化

  • 减少内存分配和释放次数:频繁的内存分配和释放会导致内存碎片和性能下降。可以通过一次性分配较大的内存块,然后在需要时重复使用,或者使用内存池技术来管理内存。

  • 优化内存访问模式:在访问多维数组时,按照内存连续的方式进行访问,可以提高缓存命中率,从而提高性能。例如,对于二维数组 int a[100][100],按 a[i][j] 的顺序访问比按 a[j][i] 的顺序访问更高效,因为前者在内存中是连续存储的。

4) 多线程和并行编程

  • 合理划分任务:将任务划分为多个子任务,分配到不同的线程或进程中并行执行,以充分利用多核处理器的性能。但要注意避免线程之间的竞争和同步问题,可使用互斥锁、信号量等同步机制来保证数据的一致性。

  • 使用线程池:避免频繁地创建和销毁线程,可使用线程池来管理线程。线程池在初始化时创建一定数量的线程,当有任务到来时,从线程池中获取空闲线程来执行任务,任务执行完毕后线程并不销毁,而是回到线程池中等待下一次任务。

2、工具

1) 编译器优化选项

  • -O 系列选项:GCC 编译器提供了不同级别的优化选项,如 -O1-O2-O3 等。-O1 会进行一些基本的优化,如减少代码大小、优化循环等;-O2 会在 -O1 的基础上进行更多的优化,包括函数内联、指令重排等;-O3 则会进行更激进的优化,如循环展开、公共子表达式消除等,但可能会增加编译时间和代码大小。

  • -finline-functions:该选项会将所有简单的函数进行内联,而不仅仅是在函数声明前添加 inline 关键字的函数,可进一步减少函数调用的开销。

2) 性能分析工具(系统级)

  • perf: Linux 内核自带的性能分析工具,功能强大。它可以用于分析 CPU 性能、内存访问、进程调度等方面的问题。例如,perf stat <可执行程序>:可以统计程序运行过程中的各种性能指标,如 CPU 时钟周期、指令数、缓存命中率等。perf record <可执行程序>:记录程序运行时的性能事件,运行结束后会生成一个数据文件,再通过 perf report 命令对该文件进行分析,生成详细的分析报告,展示各个函数的性能开销占比等。

  • top:实时显示系统中各个进程的资源占用情况,包括 CPU 使用率、内存使用率、进程状态等,可快速定位系统中占用资源较多的进程。在命令行中输入 top 后,会列出当前系统中所有进程的相关信息,按 Shift+P 可按照 CPU 使用率进行排序,按 Shift+M 可按照内存使用率排序,方便查看资源消耗大户。

  • vmstat:报告关于进程、内存、I/O 和 CPU 活动的系统级统计信息,常用于监控系统的整体性能状态和资源使用趋势。在命令行输入 vmstat <时间间隔> <次数>,如 vmstat 5 10,表示每隔 5 秒输出一次系统性能统计信息,共输出 10 次,通过这些数据可以观察到系统在一段时间内的性能变化情况。

3) 性能分析工具(应用级)

  • gprof:是 GNU 提供的性能分析工具,通过在编译时添加 -pg 选项,在程序运行结束后,会生成一个性能分析报告,显示每个函数的调用次数、执行时间等信息,帮助开发者找到程序中的性能瓶颈。

  • Callgrind:是 Valgrind 工具集的一部分,用于收集程序的调用图和函数的执行时间等信息,能够更详细地分析函数之间的调用关系和性能开销。使用 valgrind --tool=callgrind <可执行程序> 命令运行程序,运行结束后会生成一个名为 callgrind.out.<pid> 的文件,其中 <pid> 是程序的进程 ID。然后可以使用 kcachegrind 或 qcachegrind 等图形化工具来查看分析结果,直观地展示函数调用图和性能数据。

  • Intel VTune Amplifier:一款功能强大的性能分析工具,支持对 C/C++ 程序进行全面的性能分析,包括热点分析、线程分析、内存分析等,并且提供了图形化的界面,方便用户查看和分析结果。安装并打开Intel VTune Amplifier 后,创建一个新的项目,选择要分析的可执行程序,然后设置分析类型和相关参数,点击运行即可开始分析。分析结束后,在图形化界面中可以查看详细的性能数据和分析报告,如函数的执行时间、调用次数、CPU 利用率等。

4) 内存检测工具

  • valgrind:是一款用于内存调试、内存泄漏检测和性能分析的工具。它可以检测出程序中存在的内存泄漏、越界访问、非法内存访问等问题。使用 valgrind --tool=memcheck 命令可以对程序进行内存检查,它会详细地报告出程序中存在的内存问题以及问题所在的位置。

  • AddressSanitizer:是一种快速的内存错误检测工具,集成在 GCC 和 Clang 编译器中。通过在编译时添加 -fsanitize=address 选项,它可以在程序运行时检测出内存越界、使用未初始化的内存等问题,并给出详细的错误信息和调用栈。

 


http://www.kler.cn/a/453157.html

相关文章:

  • 精准识别花生豆:基于EfficientNetB0的深度学习检测与分类项目
  • @RequestParam和@PathVariable的解释与区别
  • 从自动驾驶到具身智能漫谈
  • 正则表达式(三剑客之sed)
  • HarmonyOS NEXT 实战之元服务:静态案例效果---每日玩机技巧
  • 跨境电商培训:云手机的新舞台
  • 某车之家appso层签名逆向
  • 2024楚慧杯WP
  • CultureLLM 与 CulturePark:增强大语言模型对多元文化的理解
  • 力扣-数据结构-3【算法学习day.74】
  • 存储块的获取与释放
  • Windows下ESP32-IDF开发环境搭建
  • 智源研究院与安谋科技达成战略合作,共建开源AI“芯”生态
  • 冰狐智能辅助使用插件化开发集成三方ocr
  • Linux中的lseek 函数与fcntl函数
  • CMS(Concurrent Mark Sweep)垃圾回收器的具体流程
  • 使用Python读写文本文件
  • 【2024最新】基于Python+Mysql+django的水果销售系统Lw+PPT
  • 网络层协议--ip协议
  • uni-app 中使用微信小程序第三方 SDK 及资源汇总