优化概述

优化概述

许多优化机会的出现源于某些C++特性被无用而致使程序运行缓慢、消耗许多资源,这些代码虽然是正确的,却不完善。这些代码每每是由于开发人员缺少现代微处理器设备的基本常识,或是没有仔细考虑各类C++对象构建方式的性能开销而编写出的。可进行优化的另一个缘由是,C++提供了对内存管理和复制的精准控制功能。算法

优化是软件开发的一部分

优化是一项编码活动。在传统的软件开发过程当中,直到编码完成,项目进入了集成与测试阶段,可以观察到程序总体的性能时,才会进行优化。而在敏捷开发方式中,当一个带有性能指标的特性编码完成后或是须要实现特定的性能目标时,就会分配一个或多个迭代进行优化。编程

Bug修复与性能优化之间的一个重要区别是,性能是一个连续变量。特性要么是实现了,要么是没有实现;Bug要么存在,要么不存在。可是能够是很是糟糕或者很是优秀,还多是介于这二者之间的某种程度。优化仍是一个迭代的过程,每当程序中最慢的部分被改善后,一个新的最慢的部分就会出现。缓存

与其余编码任务相比,优化更像是一门实验科学,须要有更深刻的科学思惟方式。要想优化成功,须要先观察程序行为,而后基于这些程序行为做出可测试的推测,再进行实验得出测试结果。这些测试结果要么验证推测,要么推翻推测。经验丰富的开发人员经常相信他们对于最优代码具备足够的经验和直觉。可是除非他们频繁地测试本身的直觉,不然一般他们都是错误的。实验,而非直觉,才是贯穿本书的主题。安全

优化是高效的

开发人员很难理解单个编码决策对大型程序的总体性能的影响。所以,实际上全部完整的程序都包含大量的优化机会。即便是经验丰富的团队在时间充裕的状况下编写出的代码,运行速度一般也能够提升 30%-100%。不过,经过微调代码让程序的运行速度提高10多倍几乎是不可能的,选择一种更好的算法或是数据结构,则能够将程序的某个特性的性能从慢到没法忍受提高至可发布的状态。性能优化

优化是没有问题的

“不要进行优化”这条建议被过分推崇,我以为不要过于教条,优化是没有问题的。学习高效的编程惯用法是没有问题的,即便你不知道哪部分代码的性能很重要。当你拥有良好的编程习惯,编写高效代码与编写低效无用的代码所花的时间是同样的,那为何不优化呢?数据结构

可是,若是你不清楚重要性,由于不肯定哪一个算法更好而致使许多天过去了项目仍毫无进展,这是不行的。
不知道性能问题出在哪里就花费不少时间进行优化,这是不行的。试图修改程序中的每句语句去改善程序性能没有必要,也不会有做用。只有10%的代码会对程序的性能产生显著的影响,那么试图随机找出一个性能改善切入点的几率就会很低。如何使用工具定位代码中的“热点“就很重要。并发

实际上,常识多是性能改善最大的敌人。常识的“解毒剂”是实验形式的科学方法。要学会利用工具测量软件性能,并经过实验验证优化效果。函数

C++代码优化策略总结

C++的混合特性为咱们提供了多种实现方式,一方面能够实现性能管理的全自动化,另外一方面也能够对性能进行更加精准的控制。高并发

C++有一些热点代码是性能惯犯,其中包括函数调用、内存分配和循环。如下是一份改善C++程序性能的方法总结。工具

用好的编译器并用好编译器

使用支持C++11的编译器。C++11实现了右值引用(rvalue reference)和移动语义(move semantics),能够省去许多在之前的C++版本中没法避免的复制操做。

打开编译器的优化选项。

使用更好的算法

选择一个最优算法对性能优化的效果最大。各类优化手段都能改善程序的性能,但大部分只能使程序性能呈线性提高。除非你能找到一个更加高效的算法,不然要想实现性能的指数级增加一般是不太可能的。

优化一个糟糕的算法很愚蠢。对代码优化而言,学习和使用查找和排序的最优算法才是康庄大道。替换一个更优的算法后,数据集越大,能够缩短的运行时间就越多。

使用更好的库

C++编译器提供的标准C++模板库和运行时库必须是可维护的、全面的和很是健壮的。咱们无需对这些库进行调优。虽然C++已经发明出来30年多了,商业C++编译器的库仍然有Bug,而且可能不遵循如今的C++标准,甚至不遵循编译器发布时的标准。这使得测量和推荐优化方法的任务变得很是复杂,也使得开发人员认为没有任何优化经验是能够移植的。

有一些开源库实现了很是重要的功能,如内存管理。它们提供的复杂的实现可能比供应商提供的C++运行时库更快、更强。这些可供选择的开源库的一个优点是,它们很容易地整合至现有的工程中,并可以当即改善程序性能。

最后,开发人员还能够开发适合本身项目的库,经过放松标准库中的某些安全性和健壮性约束来换取更快的运行速度。

某些方式的函数调用的开销很是大。优秀的函数库的API所提供的函数反映了这些API的惯用法,使得用户能够无需频繁地调用其中的基础函数。

要想隐藏高度优化后的程序的复杂性,函数和类库是很是适合的地方。做为调用库的回报,它们会以最高的效率完成工做。库函数一般位于深层嵌套 调用链的底端,在那里,性能改善的效果会更加明显。

减小内存分配和复制

减小对内存管理器的调用是一种很是有效的优化手段,绝大多数C++语言特性的性能开销最多只是几个指令,可是每次调用内存管理器的开销倒是数千个指令。

字符串是许多C++程序中很是重要和性能开销大的部分。

对缓存复制函数的一次调用也可能消耗数千个CPU周期。所以,减小复制是一种提升代码运行速度的优化方式。大量复制的发送都与内存分配有关,因此修改一处每每也会消灭另外一处。其余可能会发生复制的热点代码是构造函数和赋值运算符以及输入输出。

移除计算

除了内存分配和函数调用外,单条C++语句的性能开销一般都很小。但若是在循环中执行了100万次,或者每次处理时都执行这条语句,那么这就是个大问题了。绝大多数程序都会有一个或多个主要的时间处理循环和一个或多个处理字符的函数。找出并优化这些循环。

在尝试减小计算数量以前,肯定程序中哪部分会被频繁地执行。

同时,现代C++编译器在进行这些局部改善方面也作得很是优秀了。所以,不该当有强迫症,将i++都替换成++i,或是展开全部的循环,竭尽全力地向每位同时讲解什么是达夫设备以及它的优势。

使用更好的数据结构

选择最合适的数据结构对性能有着深入的影响,由于插入、迭代、排序和检索元素的算法的运行时开销取决于数据结构。除此以外,不一样的数据结构在使用内存管理器的方式上也有所不一样。另外一个缘由是数据结构可能有也可能没有优秀的缓存本地化。

提升并发性

大多数程序都须要等待。任什么时候候,若是一个程序的处理进度因须要等待这些时间被暂停,而没有利用这些时间进行其余处理,都是一种浪费。

现代计算机均可以使用多个处理核心来执行指令。若是一项工做被分给几个处理器执行,那么它能够更快地执行完毕。

伴随并发执行而来的是用于同步并发线程让它们能够共享数据的工具。

优化内存管理

内存管理器做为C++运行时库中的一部分,管理着动态内存分配。它在许多C++程序中都会被频繁地执行。C++确实为内存管理提供了丰富的API,虽然多数开发人员都历来没有使用过。

相关文章
相关标签/搜索