C++优化系列之性能调优工具篇

大家好,我是程序喵,虽然假期都快过去了,有很多朋友问程序喵怎么没更文呢?是不是偷懒了!其实我这几天没闲着,一直在整理学习资料,昨晚终于完成了,估计这两天会跟大家见面。

图片

好了,我们CPP优化系列正式开始!今天的文章里,我会介绍一些常用的工具,帮助大家找到代码的“坏味道”(潜在的坑),进而提升代码质量。

那到底什么样的代码才算是高质量代码呢?

 

对此我整理了一份脑图:

图片

如何能够提升代码质量呢,除了我们自身过硬的编码能力,还需要制定代码检查流程,一般代码检查有以下几种方式:

图片

代码检查要检查的问题有:

图片

脑图中有一些代码度量指标,它用于量化代码质量:

如果代码的圈复杂度或认知复杂度过大,可能函数本身实现的过于复杂,或可能因为架构设计过于复杂,导致函数过于复杂。

如果函数嵌套过深,说明函数很可能出错,需要仔细进⾏⼈⼯评审,并且函数可能需要重构。

如果模块的扇入过大,说明模块可能是公共模块,需要⼈⼯评审接⼝是否是稳定的,或模块承担过多职责,可以考虑遵循单⼀职责,分解模块的职责。

如果模块的扇出过大,说明该模块依赖多个模块,可以考虑把被依赖的多个模块合并为⼀个模块,重构依赖的接⼝。

如果类的继承树过深,考虑在继承树的深度上是否有新的变化⽅向,考虑提出新的策略类,或其他设计模式来优化继承树。

如果子类过多,检查⼦类的实现中共同的地⽅,先考虑提出公共的中间⼦类,检查是否可以通过桥接模式、装饰模式、组合模式等结构型模式重构代码。

 

上面脑图所说的需要检查的各种问题中,代码和需求背离问题与代码是否符合设计问题需要人工评审,成本较高,其它问题可以通过工具来检测。

 

检测工具主要分为静态代码分析工具和动态代码检测工具。

 

静态代码分析工具主要用于静态代码分析,关于静态代码分析,它能够根据规则帮助检查代码缺陷,然而,对于检查规则能够覆盖的代码,工具能够工作的挺好,但对于规则没有覆盖的代码,它却无能为力,而且可能存在误报问题。

 

静态代码分析是保证代码质量的重要手段,据说软件开发中大概30%-70%的代码逻辑设计和编码缺陷都可以通过静态代码分析来发现和修复。它会扫描程序代码,找出代码中隐藏的错误,如参数不匹配、有歧义的嵌套语句、错误的递归、非法计算、空指针问题、越界问题、未初始化问题、内存泄漏问题等。

 

静态代码分析工具的优势有:

  1. 自动执行静态代码分析,快速定位代码隐藏错误和缺陷

  2. 帮助代码设计人员更专注于分析和解决代码设计缺陷

  3. 减少在代码人工检查上花费的时间,提高软件可靠性并节省开发成本

 

举例如下:

代码规范检查:由于拷贝粘贴造成两个分支的代码完全相同

void func(int in, int &out) {
    if (in > 1) out++;
    else out++;
    out++;
}

代码缺陷检查:没有用的RAII

void func() {
    std::lock_guard<std::mutex>(lk); // 临时对象,语句结束后执行析构,误用的加锁
    ...
}

下面是一些常见的静态代码分析工具:

图片

这里推荐一个常用的代码质量管理平台SonarCube,SonarQube是一个管理代码质量的平台(社区版免费),用于管理代码的质量,它会从多个角度维护检测代码质量,通过插件形式支持多种语言的代码质量管理和检测。它可以安装sonar-cxx插件,内置了一系列C/C++代码检查工具,还可以应用在CI/CD流程中,和Jenkins打通,可以在提交代码后检查代码是否有坏味道,不符合规范的代码就拒绝被合入master。

 

还有一个很好用的静态代码检测工具是Facebook的infer,它最大的优势是可以静态检测代码内隐藏的内存泄漏问题,而且免费支持Android、C、OC语言。

 

静态代码分析工具可以在运行前帮助我们检测缺陷,只有30%-70%,但不是所有缺陷,很多缺陷需要在运行时才会被发现。

 

其实我们还可以使用一些动态分析工具,通过动态分析工具可以准确定位问题,而且误报率低,但这与测试用例强绑定,查找缺陷的比例与测试用例的覆盖率有关,覆盖率对于衡量代码质量有很大意义。

 

代码覆盖率的意义:

● 帮助我们找到未覆盖部分的代码,分析测试用例设计的是否充分,之后视情况决定是否可以补充测试用例。

● 检测出代码的坏味道,提示我们修改代码,理清代码逻辑关系,提升代码质量。

● 代码覆盖率高不能代表代码质量一定好,但代码覆盖率低,代码质量估计不会高到哪去,可以作为我们衡量代码质量的重要手段之一。

● 对于没有覆盖到的错误,动态分析工具也无能为力。在实际工作中,我们可以动静结合,多种检查手段全都用上,可以更有效的提升代码质量。

 

动态分析工具可以在程序运行时发现代码的缺陷,例如内存问题、数据竞争、未定义行为等。

 

常用工具有GCC&Clang的Santizer系列:

● Asan-Address Sanitizer:缓存区溢出,内存泄漏

● Tsan-Thread Sanitizer:并发问题

● Msan-Memory Sanitizer:未初始化内存

● Ubsan-Undefined Behavior Sanitizer:未定义行为

● 编译选项添加fsanitize=address/memory/thread/undefined

 

还有Valgrind工具:

● memchek:内存问题,包括Asan和Msan

● helgrind:线程和并发问题

● cachegrind、callgrind、massif:帮助进行性能优化

 

使用各种工具与单元测试、功能测试、系统测试结合,提高覆盖率,可以帮助我们发现更多缺陷。

前面的多数都是代码分析工具,下面介绍一些性能分析工具,关于性能分析工具Brendan Gregg大佬的网站介绍的很详细,这里贴出来一张他总结的工具图:

图片

这张图从Linux内核的各个子系统出发,汇总了对各个子系统进行性能分析时可以选择的工具。其实还有一些好用的工具,图里没有提到,这里重点介绍一下:

gprof:gprof是GNU工具之一,编译的时候,它在每个函数的出入口加入了profiling的代码,运行时统计程序在用户态的执行信息,可以得到每个函数的调用次数,执行时间,调用关系等信息,简单易懂。适合于查找用户级程序的性能瓶颈,然而对于很多耗时在内核态执行的程序,gprof不适合。

Oprofile:Oprofile也是一个开源的profiling工具,它使用硬件调试寄存器来统计信息,进行profiling的开销比较小,而且可以对内核进行profiling。它统计的信息非常多,可以得到cache的缺失率,memory的访存信息,分支预测错误率等等,这些信息gprof得不到,但是对于函数调用次数,它无能为力。

简单来说,gprof简单,适合于查找用户级程序的瓶颈,而Oprofile稍微有点复杂,但是得到的信息更多,更适合调试系统软件。

gperftools:Google出品,值得信赖,提供整个程序的热点分布图,找到性能瓶颈,然后可以针对性的进行性能优化,如图:

图片

我们平时编程过程中可能很多时候都会使用某些时间API来计算函数耗时,使用方式可以看我的这篇文章:《详细介绍下C/C++时间相关的那些函数

那使用什么API效率更高呢,可以看下图:

图片

图中的rdtsc使用较繁琐而且不适用于所有平台和编译器,剩下的大家可以按需使用哈。

关于性能分析工具,程序喵整理了一份非常详细的脑图(精华全在脑图里),以性能指标分类,不同指标使用什么工具进行分析,都在图里,目录如下:

图片

参考资料

https://stackoverflow.com/questions/375913/how-can-i-profile-c-code-running-on-linux

https://zh.wikipedia.org/wiki/%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90

https://www.cnblogs.com/bangerlee/archive/2012/08/30/2659435.html

http://www.brendangregg.com/linuxperf.html

https://www.cnblogs.com/youxin/p/7988479.html

https://www.agner.org/optimize/

https://zhuanlan.zhihu.com/p/141694060

https://www.wyyuan.com/2018/11/06/%E8%AE%A4%E7%9F%A5%E5%A4%8D%E6%9D%82%E5%BA%A6/

http://bitjoy.net/2017/02/07/introduction-to-performance-analysis-tools-in-linux/

 

  • 8
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《提高C性能的编程技术》是一本有关优化C语言程序性能的编程指南。本书的目的是为开发人员提供一系列实用的技术和策略,帮助他们优化C语言程序的性能。 首先,本书介绍了一些性能优化的基本概念和原则,如减少循环次数、降低内存访问延迟等。通过了解这些基本原则,开发人员可以更好地理解性能优化的重要性,并能够在实际编程中应用这些原则。 其次,本书介绍了一些具体的优化技术和方法。例如,使用合适的数据结构和算法可以提高程序的执行效率;正确地使用指针和数组可以减少内存占用和提高访问速度;合理地使用编译器优化选项可以改善程序的性能等等。这些技术和方法都是在实际应用中经过验证的,可以帮助开发人员充分利用C语言的特性和优势,达到性能优化的目的。 此外,本书还介绍了一些常见的性能优化问题及其解决方法。例如,如何避免伪共享、如何减少内存碎片等。对于遇到这些问题的开发人员来说,本书的指导将非常有价值。 总之,《提高C性能的编程技术》是一本非常实用的编程指南,可以帮助开发人员提高C语言程序的性能。通过深入理解性能优化的原则和方法,开发人员能够编写出更高效、更优化的程序,提高系统的响应速度和性能。这对于提升用户体验、优化资源利用非常重要。读者可以通过阅读本书,了解C语言性能优化的最佳实践,并将其应用于实际项目中。 ### 回答2: 《提高C性能的编程技术》是一本关于提高C语言程序性能的编程指南,旨在帮助开发者了解和使用各种编程技术以优化C语言程序的性能。 该书介绍了一系列的编程技术和最佳实践,可以帮助开发人员在编写C语言程序时对性能进行优化。 首先,该书介绍了一些基本的性能调优原则,例如减少函数调用、避免频繁的内存分配和释放等。这些原则可以帮助程序员在最初的设计和开发阶段就考虑性能问题,从而避免后期的性能瓶颈。 另外,该书还详细介绍了一些针对C语言的特定编程技术,如使用位运算替代乘法和除法、使用寄存器变量优化循环等。这些技术可以显著提高程序的执行速度和效率。 此外,该书还详细介绍了一些常用的性能调试工具和性能优化方法,如使用性能分析器识别程序的性能瓶颈,并给出了一些优化建议。这些工具和方法可以帮助开发者定位和解决程序的性能问题。 总之,《提高C性能的编程技术》是一本非常实用的指南,对于想要优化C语言程序性能的开发人员来说具有很大的帮助。通过学习和应用该书中的编程技术,开发者可以提高程序的执行效率,从而提升软件的性能和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序喵大人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值