C++应用程序性能优化(一)——应用程序性能优化简介

C++应用程序性能优化(一)——应用程序性能优化简介

1、程序性能优化简介

一、程序性能优化简介

在计算机发展的早期阶段,硬件资源相对而言是很是昂贵的,CPU运行时间与内存容量给程序开发人员设置了极大限制。所以,早期的程序对运行性能和内存空间占用的要求是很是严格的,不少开发人员为了减小1%的CPU运行时间,为减小几十个甚至几个字节而不懈努力。随着计算机技术的快速发展,硬件资源变得相对便宜。但若是认为软件开发时,程序的性能优化再也不重要,硬件将解决性能问题也是片面的。计算机硬件的发展解决了部分软件的性能问题,但随着硬件计算能力的提升,用户对软件功能的要求也愈来愈高,软件功能也变得愈来愈复杂,给用户的界面和操做体验也愈来愈智能和友好。但复杂的用户需求带来软件性能上的要求是硬件不能彻底解决的。众多实际项目经验证实,若是在开发软件时不重视性能优化,最终实现了软件的功能要求,但软件的运行效率低下,最终也不能给用户带来很好的效益。但另外一方面,计算机硬件愈来愈便宜,而优秀的软件开发工程师则愈来愈昂贵,在软件开发过程当中无限制的性能优化一样会致使软件开发过程当中人力成本的大幅增长。所以,软件开发过程当中的性能优化必须在便宜的计算机硬件和昂贵的优秀工程师之间找到一个平衡点。ios

二、程序性能优化的流程

应用程序性能优化的流程以下:
C++应用程序性能优化(一)——应用程序性能优化简介
(1)性能测量,对于规模较大、较为复杂的软件系统,测量性能数据是进行性能优化的基础。只有获取真实的数据才能分析数据找出系统的性能瓶颈。
(2)分析数据,找到系统的性能瓶颈。性能瓶颈必须创建在客观真实的性能数据基础上,不能是主观臆测的。
(3)分析缘由,修改程序,是程序性能优化的核心。程序的性能包括启动速度、运行速度、运行时占用内存等。影响程序性能的因素主要分为两类:
(1)软件编程设计因素:算法和数据结构的选择,编程语言的使用。
(2)软件系统结构因素:动态库、静态库的组织,外部数据的存储以及网络环境等。
软件编程设计因素是对软件性能影响较大的因素,只有对算法、数据结构、编程语言有深刻的了解才能分析出缘由,而且找到解决性能问题的方法。
软件系统结构因素一般与操做系统紧密相关。对于现代软件,因为功能复杂,一般采用组件形式,以最大限度的提升可复用性。所以,通常会包含一些动态库、静态库,库文件的组织也会影响到软件系统的性能。算法

2、程序性能的定义

一、性能指标定义

应用程序的性能指标一般是多维的,好比响应时间、并发量等。对于桌面应用程序,其服务对象一般为终端用户。所以,桌面应用程序最重要的性能指标是响应时间,即针对某一个具体的操做,用户从发出命令到应用程序完成任务并响应用户的时间,响应时间越短越好。
除了响应时间,内存使用也是桌面应用程序的重要指标之一。内存使用包括进程工做集(任务管理器看到的内存使用)和虚拟内存使用两个指标,越小越好。若是一个应用程序占用内存太高,会影响其它正在运行的应用程序的响应时间。
根据可用性设计,桌面应用程序的设计原则以下:
(1)小于0.1秒的响应时间,用户感受是即时的。
(2)小于1秒的响应时间,用户感受是可接受的。
(3)大于1秒的操做应该有一个简单标示(如鼠标变成沙漏)。
(4)大于10秒的操做应该有明显的提示(如进度条)。编程

二、性能基准

桌面应用程序的性能指标包括响应时间和内存使用,但响应时间和内存使用指标一般针对单个操做。现代软件系统一般包括多项功能,例如一个文字处理软件可以提供的功能不下数百种,每种功能做用在不一样类型和大小的文档上会表现出不一样的性能,性能基准就是用于定义程序的整体性能的。
性能基准(Performance Benchmark)是用来衡量应用程序总体性能的一套体系,经过为应用程序输入预先设计好的工做负载,运行一批基准用例,运行结果能够反映应用程序在一般状况下的性能。所以,性能基准=基准负载+基准用例。
(1)基准负载
对于桌面应用程序,运行性能基准时须要的基准负载一般表现为一系列基准文件。基准文件应该是具备典型大小和典型内容的文件,而基准文件选取的优劣直接影响性能基准的准确性。
对于通用文字处理软件,主要功能是建立、打开文档,修改并保存文档,支持的文档类型包括.doc,.dot,.odt,.ott,.txt,.lwp等,支持文字、图片、文本框、表格、图形等。设计基准文件时,从文档类型考虑,在兼顾到主要的文档类型又要排除相似的文档类型;从文档内容考虑,须要覆盖用户最经常使用的内容对象类型和文档大小,具体基准文件列表以下:
C++应用程序性能优化(一)——应用程序性能优化简介
对于同一种文档类型,每一种文档类型包含两个基准文件,分别有不一样的文档内容。
(2)基准用例
基准用例是性能基准测试时须要执行的一系列用例。基准用例的选择有必定原则,既要尽量全面地覆盖应用程序的主要功能,又不能像功能测试用例那样复杂,所以,基准用例应该是用户平常操做常常遇到的情形。
不一样的基准用例在性能基准中的地位并不相同,每个基准用例都须要一个权值来代表它对总体性能基准的贡献度。权值的定义依据具体状况各有不一样,一个比较实用的定义公式以下:
权值=用例频率X用例重要性
用例频率是用户必定时间内执行该用例的平均次数。理想的用例频率应该经过用户行为数据反馈得到。例如通用文字处理软件的用户一天内可能会执行“打开文档”用例5次,执行“保存文档”的用例15次。
用例重要性是一个修正系数,反映用例没有完成前对用户工做的影响程度。文字处理软件打开一个文档时有“异步打开”的功能,即程序会首先读入文档的部份内容并显示给用户,而后在后台继续读入文档的后续内容。对于“异步打开”功能能够定义两个用例,“第一页显示”(从用户选择打开文档到文档的第一页显示出来的过程)和“所有读入完毕”(从用户选择打开文档到文档的全部页的内容已经加载完毕的过程)。“第一页显示”用例的重要性为1,表示不执行完本用例,用户不能继续工做;“所有读入完毕”用例的重要性为0.5,表示本用例不会显著影响用户的工做,文档在后台加载,用户前台已经能够编辑,除非用户须要编辑的内容尚未加载出来。
文字处理程序的部分基准用例以下:
C++应用程序性能优化(一)——应用程序性能优化简介
相同的操做步骤操做不一样类型或不一样内容的基准文件会造成不一样的基准用例。缓存

三、性能基准的运行

准备好基准文件和基准用例后就能够运行性能基准并得出基准结果。
为了保证性能基准运行的准确性,性能基准的测试环境必须知足必定要求。例如保证固定的基准测试平台(软件和硬件平台不变),尽量排除其它应用程序对目标应用层程序的影响。基准测试平台也能够有同时运行在多种硬件平台上的考量:运行在4G内存和8G内存时应用程序的性能表现的差异;运行在三年前硬件配置和当前主流硬件配置的性能表现的差异。
运行基准测试的过程是在固定的基准测试环境中针对基准文件顺序执行一系列基准用例并记录下每一个用例结果的过程,执行过程分为手动执行和自动执行,结果记录也能够分为手动记录和自动记录。
一般手工执行和记录是基础,最能反映最终用户的体验。
自动运行和记录是目标,能够大幅提高工做效率,并排除人工不稳定的结果。但自动运行的脚本必须保证屡次自动运行结果的稳定,保证自动运行结果和手动运行结果的可比较。
性能基准运行的过程须要注意:
(1)每个用例须要运行屡次求平均值,如须要去除最大值、最小值,而后取平均值。
(2)多个用例执行的前后顺序必须固定,不然很可贵到稳定的性能基准结果。性能优化

四、性能基准结果

性能基准运行结果的原始数据是一系列的绝对数值,能够根据不一样的须要生成不一样的报告,如:
总体性能水平分值:每一个用例绝对值结合每一个用例的权值,能够给总体性能水平打分。
性能变化趋势图:历史上不一样版本的总体性能分值曲线能够体现出性能变化趋势。
关键性能指标图表:给用户演示的重点用例的结果图表。
产品性能对比图:和其它产品的性能对比图,包括绝对值的对比和加权后分值的对比。
文字处理程序的部分基准用例运行结果数据以下:
C++应用程序性能优化(一)——应用程序性能优化简介
性能基准能够反映应用程序的整体性能,定义良好的性能基准用途以下:
(1)应用程序性能的绝对指标。任何想要了解产品性能的人,不管是管理层仍是客户,均可以经过产品性能报告了解产品的性能。
(2)经过比较不一样版本的基准结果,提早发现性能降低的问题和验证性能提高的设计结果。软件开发过程当中一般都会进行每日构建,性能基准也能够在每日构建的基础上每日运行,及时发现性能问题,而不是在产品即将发布时进行性能优化。
(3)比较不一样厂商的相似软件的性能。横向的比较须要性能基准,能够找出本身软件产品的性能薄弱环节,集中力量进行优化。网络

3、程序性能分析方法

一、性能分析方法简介

拥有定义良好的性能基准后,能够轻易发现应用程序存在的性能问题。发现性能问题后须要对性能问题进行分析,程序的性能分析过程包括:性能问题分类、查找性能瓶颈、进行性能优化。数据结构

二、性能问题分类

一个操做执行太慢,须要首先分类是IO操做密集引发的问题仍是CPU相关的计算密集型问题。正确的分类将直接影响进一步的问题分析。
区别IO相关仍是CPU相关问题的简单方法是隔离IO影响后,看性能是否获得改善,例如同时在机械硬盘和SSD硬盘上测试,若是性能显著提升,则是IO相关的问题。
对于文字处理软件,冷启动须要10.5秒,热启动须要2.1秒,所以冷启动的主要问题在IO。不管是冷启动仍是热启动,应用程序都是彻底退出后再从新启动,执行的代码流程彻底同样,惟一区别在于IO:冷启动后操做系统会缓存不少动态库的代码页在内存。架构

三、查找性能瓶颈

对性能问题分类后,可使用性能分析工具在代码层次查找性能瓶颈,性能分析工具备监测工具和注入工具两类。
监测工具以下:
perfmon,Windows工具,能够监测全部的性能指标。
FileMon,Windows工具,监测IO操做。
ProcessExplorer,Windows工具,监测进程相关的全部操做。
sysstat,Linux工具,监测全部的性能指标。
iostat,Linux工具,监测IO操做。
vmstat,Linux工具,监测内存变化。
注入工具以下:
IBM rational quantify,Windows工具,针对C++应用程序代码注入,能够计算函数调用次数、时间等。
Valgrind,Linux工具,针对C++应用程序代码注入,能够计算函数调用次数、事件、内存分配、内存泄漏检测等。
IBM rational purify,Windows工具,针对C++应用程序代码注入,能够进行内存分析。
WinDbg,Windows工具,调试工具。
GDB,Linux工具,调试工具。
Dependency walker,Windows工具,分析动态连接库之间的动态、静态依赖关系。
ldd,Linux工具,分析共享对象间的依赖关系。并发

四、查找性能优化机会

代码层次的性能优化设计的改动一般局限在有限的函数调用内,相对比较容易完成。进一步的性能提高的机会须要在设计层次进行查找。设计层面的性能分析须要性能优化者对软件的总体架构有比较深刻的了解,须要具体问题具体分析。异步

4、程序性能优化方法

性能问题分析完成后,须要进行性能优化。根据性能分析结果的不一样,优化方法也各有不一样。

一、针对IO瓶颈的性能优化

每次IO操做大概在10ms量级,100次就须要1秒左右,所以尽可能避免没必要要的IO操做。具体作法以下:
(1)预先顺序读文件避免随机访问。
(2)合并多个小文件为单个大文件。
(3)优化动态库文件的加载。
(4)交错IO时间和CPU时间。

二、针对计算密集的性优化

计算密集的性能问题主要有内存分配性能、字符串操做、共享变量的互斥锁保护等,具体优化方法以下:
(1)去除冗余代码。
(2)字符串操做优化。
(3)减小内存分配、释放操做,例如使用内存池。
(4)减小没必要要的互斥锁操做。
(5)根据性能需求选择数据结构。
(6)延迟工做,按需执行。
(7)减小跨进程的调用。
(8)使用高性能的函数库。

三、C++语言特性相关的性能优化

C++语言特性相关的性能优化包括内联函数、引用、编译优化选项等。

四、用户体验的性能优化

有些设计不能真正提高性能,但让用户体验到了性能提高。如:
(1)流式播放设计,用户不须要等到视频文件下载完成再播放,能够边下载边播放。
(2)线程化设计,对于须要较长时间完成的操做,能够设计为非阻塞式的,用户能够在等待时间完成其它操做任务。

五、设计层面的性能优化

设计层面的性能优化须要根据软件总体架构具体问题具体分析。

相关文章
相关标签/搜索