原文:http://www.cnblogs.com/me115/archive/2013/06/05/3117967.html

内容目录:

  • 1 Gprof
  • 2. gprof使用步骤
  • 1.初始化大对象耗时
  • 2.Map使用不当

优化准则:

1. 二八法则:在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%的尽管是多数,却是次要的;在优化实践中,我们将精力集中在优化那20%最耗时的代码上,整体性能将有显著的提升;这个很好理解。函数A虽然代码量大,但在一次正常执行流程中,只调用了一次。而另一个函数B代码量比A小很多,但被调用了1000次。显然,我们更应关注B的优化。
2. 编完代码,再优化;编码的时候总是考虑最佳性能未必总是好的;在强调最佳性能的编码方式的同时,可能就损失了代码的可读性和开发效率;

工具:

1 Gprof

工欲善其事,必先利其器。对于Linux平台下C++的优化,我们使用gprof工具。gprof是GNU profile工具,可以运行于linux、AIX、Sun等操作系统进行C、C++、Pascal、Fortran程序的性能分析,用于程序的性能优化以及程序瓶颈问题的查找和解决。通过分析应用程序运行时产生的“flat profile”,可以得到每个函数的调用次数,消耗的CPU时间(只统计CPU时间,对IO瓶颈无能为力),也可以得到函数的“调用关系图”,包括函数调用的层次关系,每个函数调用花费了多少时间。

2. gprof使用步骤

1) 用gcc、g++、xlC编译程序时,使用-pg参数,如:g++ -pg -o test.exe test.cpp编译器会自动在目标代码中插入用于性能测试的代码片断,这些代码在程序运行时采集并记录函数的调用关系和调用次数,并记录函数自身执行时间和被调用函数的执行时间。
2) 执行编译后的可执行程序,如:./test.exe。该步骤运行程序的时间会稍慢于正常编译的可执行程序的运行时间。程序运行结束后,会在程序所在路径下生成一个缺省文件名为gmon.out的文件,这个文件就是记录程序运行的性能、调用关系、调用次数等信息的数据文件。
3) 使用gprof命令来分析记录程序运行信息的gmon.out文件,如:gprof test.exe gmon.out则可以在显示器上看到函数调用相关的统计、分析信息。上述信息也可以采用gprof test.exe gmon.out> gprofresult.txt重定向到文本文件以便于后续分析。

以上只是gpro的使用步骤简介,关于gprof使用实例详见附录1;

实践

我们的程序遇到了性能瓶颈,在采用架构改造,改用内存数据库之前,我们考虑从代码级入手,先尝试代码级的优化;通过使用gprof分析,我们发现以下2个最为突出的问题:

1.初始化大对象耗时

分析报告:307 6.5% VOBJ1::VOBJ1@240038VOBJ1
在整个执行流程中被调用307次,其对象初始化耗时占到6.5%。
这个对象很大,包含的属性多,属于基础数据结构;
在程序进入构造函数函数体之前,类的父类对象和所有子成员变量对象已经被生成和构造。如果在构造函数体内位其执行赋值操作,显示属于浪费。如果在构造函数时已经知道如何为类的子成员变量初始化,那么应该将这些初始化信息通过构造函数的初始化列表赋予子成员变量,而不是在构造函数函数体中进行这些初始化。因为进入构造函数函数体之前,这些子成员变量已经初始化过一次了。
在C++程序中,创建/销毁对象是影响性能的一个非常突出的操作。首先,如果是从全局堆中生成对象,则需要首先进行动态内存分配操作。众所周知,动态分配/回收在C/C++程序中一直都是非常耗时的。因为牵涉到寻找匹配大小的内存块,找到后可能还需要截断处理,然后还需要修改维护全局堆内存使用情况信息的链表等。
解决方法:我们将大部分的初始化操作都移到初始化列表中,性能消耗降到1.8%。

2.Map使用不当

分析报告:89 6.8% Recordset::GetField
Recordset的getField被调用了89次,性能消耗占到6.8%;
Recordset是我们在在数据库层面的包装,对应取出数据的记录集;(用过ADO的朋友很熟悉);由于我们使用的是底层c++数据库接口,通过对数据库原始api进行一层包装,从而屏蔽开发人员对底层api的直接操作。这样的包装,带来的好处就是不用直接与底层数据库交互,在代码编写方面方便不少,代码可读性也很好;带来的问题就是性能的损失;

分析:(2点原因)
1)在GetField函数中,使用了map[“a”]来查询数据,如果找不到“a”,则map会自动插入key ”a”,并设value为0;而m.find(“a”)不会自动插入上述pair,执行效率更高;原有逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    string Recordset::GetField(const string &strName)
{
    int nIndex;
    if (hasIndex==false)
    {
        nIndex = m_nPos;
    }
    else
    {
        nIndex = m_vSort[m_nPos].m_iorder;
    }
    if (m_fields[strName]==0)
    {
        LOG_ERR("Recordset::GetField:"<<strName<<" Not Find!!");
    }
    return m_records[nIndex].GetValue(m_fields[strName] - 1) ;
}

改造后的逻辑:

1
2
3
4
5
6
7
    string Recordset::GetField(const string &strName)
{
    unordered_map::iterator iter = m_fields.find(strName);
    if (iter == m_fields.end())
    {
        LOG_ERR("[Recordset::GetField] "<< strName <second - 1) ;
}

调整后的Recordset::GetField的执行时间约是之前的1/2;且易读性更高;

2)在Recordset中,对于每个字段的存储,使用的是map m_fields; g++中的stl标准库中默认使用的红黑树作为map的底层数据结构;
通过附录中的文档2,我们发现其实有更快的结构, 在效率上,unorder map优于hash map, hash map 优于 红黑树;如果不要求map有序,unordered_map 是更好的选择;
解决方法:将map结构换成unordered_map,性能消耗降到1.4%;

总结

我们修改不到30行代码,整体性能提升10%左右,效果明显;打蛇打七寸,性能优化的关键在于找准待优化的点,之后的事,也就水到渠成;

附录:

附1:prof工具介绍及实践
附2: map hash_map unordered_map 性能测试

c++优化工具Gprof相关推荐

  1. Linux性能优化工具:gprof简记

    1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺. 2. gprof工作基本原理 在使用gcc编译时指定-pg选项,编译器在用户代码中插入性能测试代码. 3. ...

  2. linux perf - 性能测试和优化工具

    Perf简介 Perf是Linux kernel自带的系统性能优化工具.虽然它的版本还只是0.0.2,Perf已经显现出它强大的实力,足以与目前Linux流行的OProfile相媲美了. Perf 的 ...

  3. GEMM性能提升200倍,AutoKernel算子优化工具正式开源

    作者 | OPEN AI LAB 研究员 吕春莹 出品 | AI科技大本营 头图 | CSDN下载自视觉中国 随着AI技术的快速发展,深度学习在各个领域得到了广泛应用.深度学习模型能否成功在终端落地应 ...

  4. 4 个 MySQL 优化工具 AWR,帮你准确定位数据库瓶颈!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源:今日头条,作者:老王谈运维 www.toutiao.com/ ...

  5. python代码规范 自动优化工具Black

    自动优化工具Black 在众多代码格式化工具中,Black算是比较新的一个,它***的特点是可配置项比较少,个人认为这对于新手来说是件好事,因为我们不必过多考虑如何设置Black,让 Black 自己 ...

  6. qt listwidget 关键字颜色_关键字排名优化工具方案

    关键字排名j67745优化工具方案,企业经常采用SEO优化,以获得更好的排名和更好的流量自己的网站.搜索引擎优化有哪些方法?或者什么更有效? 北京seo优化如何稳定网站排名,seo优化首先需要做好内容 ...

  7. 美团点评SQL优化工具SQLAdvisor开源

    介绍 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 SQL 优化,不仅可以提升程序性能,还能够降低线上故障的概率. 目前常用的 SQL 优化方式包括但不限于:业务层优化.SQL逻 ...

  8. 高级SQL优化(三) 常用优化工具 ——《12年资深DBA教你Oracle开发与优化——性能优化部分》...

    目录: Oracle数据完整性和锁机制  索引及优化之表分析  表分析.约束及表间关系  Oracle体系结构1 Oracle体系结构2  海量数据库及分区1  海量数据库及分区2  海量数据库及分区 ...

  9. Windows内存管理机密+揭穿内存优化工具的骗局

    原文:The Memory-Optimization Hoax:RAM optimizers make false promises 作者:Mark Russinovich 译者:盆盆   我们在浏览 ...

最新文章

  1. Cosmos的基石:IL2CPU编译器--.net/C#开源操作系统学习系列三
  2. 石川es6课程---6、解构赋值
  3. 获取站点某一目录下某些文件
  4. [组合数]求组合数的几种方法总结
  5. MYSQL学习笔记 (三)JOIN用法
  6. RHEL5.8安装Oracle10g
  7. Centos7 安装gitlab 8.7.5
  8. ASP.NET Core 双因素验证2FA 实战经验分享
  9. linux修改文件没有备份文件,linux文件或目录权限修改后如何恢复(备份了权限就能恢复)...
  10. GIS实战应用案例100篇(八)-桩号相同,坐标不同,RTK怎么输入曲线要素?
  11. Spring中RedirectAttributes对象重定向传参
  12. 基于JAVA+SpringMVC+Mybatis+MYSQL的粮店粮食库存管理系统
  13. 【译】Vue 的小奇技(第七篇):在 vue-multiselect 基础上创建 ImageSelect 组件
  14. 解决Eclipse中文乱码的问题
  15. Fragment与Activity
  16. 中信银行王燕:数据治理在当今银行的作用价值与实战建议
  17. Ti芯片 bq76940锂电池管理系统BMS资料,源程序+PDF原理图,主控stm32f030。
  18. 静态市盈率和动态市盈率
  19. BEEF的搭建与使用
  20. python turtle画彩虹的源代码_Python基础实例——绘制彩虹(turtle库的应用)

热门文章

  1. thonny python ide_学习用 Thonny 写代码:一个面向初学者的Python IDE
  2. 厉害的组件_企业级React UI组件库——React Suite
  3. 济南职业学院计算机信息管理在哪个校区,计算机学院圆满完成省计算机信息管理专业教学指导方案开发...
  4. 缓冲区溢出_了解Java缓冲池
  5. MoreUnit与MoreUnit
  6. html 文字倒映效果,HTML图片CSS滤镜—倒影效果
  7. Java 语言中十大“坑爹”功能!
  8. 赠书|零压力入门算法的顶流畅销书《漫画算法》
  9. linux pfn,ARM Linux下的page和pfn之间转换的宏。
  10. hm55主板支持最大内存_内存频率取决于CPU还是主板?内存频率看主板支持还是看CPU支持?...