程序性能优化

原创 2010年06月24日 23:01:00

 

卷首语:这个《面试宝典》名字是我一贯的标题党风格,其实在内容上都是很简单、很基础的——都是那种“不知道这些就别出来混”的知识点。所以,高手/牛人可以到此打住了——端咖啡——送客~~~

作/译序:此文可能会持续更新直到补充得比较完整为止,有什么要补充的欢迎留言

基础原则之万能利器:Profiling

如何测量距离?——直尺/游标卡尺/卷尺/etc
如何测量电压?——电压表/万用表
如何测量时间?——钟表/秒表
如何测量温度?——温度计
如何测量质量?——天平/台秤/etc
如何测量程序性能?——Profiler !

是的,Profiler就是这么一件又基础又重要的工具(小标题里的“万能”是标题党了)。要回答“程序为什么慢/什么地方慢/到底有多慢”等问题,离不开Profiler,就像测量长度离不开尺子一样。 (嗯,那位要测地月距离的,别抬杠了,请移步回你的实验室吧,我知道你是rocket scientist,高科技呢:)

可以使用软件Profiler,也可以使用硬件来做Profiling(DSO/Logic Analyzer/Hybrid DSO/Timer),在什么都没有的情况下,至少也可以输出Log或者用其它方式来达到Profiling的目的。
一般来说,测量工具对被测目标应该没有影响(或者极小),但是软件的Profiler却对被测目标有一定程度的影响——以此为代价,换来的是方便和廉价(免费)。

在系统外部对性能进行测试,也是一种测量性能的方式,只不过它所测量的粒度很大,不能用于分析源码,只能用于比较不同源码的优劣。

如何进行性能优化?

基本原则

原则:使用Profiler来找出最影响性能的那些程序,重点优化它们
分类:基本知识
提示:时刻记心间

原则:无论尝试了何种优化,都要使用profiler来测量这种优化
分类:基本知识
提示:时刻记心间

原则:二八原则
分类:基本知识
提示:运行中的软件有一种典型情况:20%的程序占了80%的运行时间,优化的重点是这20%的程序(20%和80%为约数)。应当使用Profiler来找出它们,改进它们并继续用Profiler测量改进的效果——在没有明显的性能热点的时候,就要考虑换一种思路进行优化了:比如使用“硬件优化”(参见下文)。在切换了设计和体系结构后,之前做的profiling也有可能会失效,要重新进行测量,每一种判断和决策必须得到证据的支持。

硬件优化

原则:使用更快的设备/通讯协议
分类:硬件优化
提示:有时候需要尝试跳出软件优化的框框来想问题
范例:使用SSD代替机械硬盘,在IO速率上你能提高2-5倍(在无RAID的情况下),在寻道时间上你能提高4个数量级(WOW!)

原则:对硬件友好
分类:硬件优化
范例:利用SIMD指令(如视频编码器);对Cache友好(数据Cache和指令Cache);对流水线友好(比如threaded code,削减分枝预测失误。注意这里的thread不是“线程”,是“线索化”);使用硬盘的外圈以达到更大的速度;

原则:利用硬件加速
分类:硬件优化
范例:使用D3D/OpenGL,使用GPU计算(如FFT),使用DMA不使用PIO,使用ASIC代替CPU进行专用计算(如常见的视频编解码专用芯片,还有加解密芯片),使用DSP对高负载数据进行处理(或预处理)

设计优化

原则:使用分布式计算
分类:设计优化
范例:使用Hardoop Hadoop;使用Memcached

原则:改进业务逻辑
分类:设计优化
备注:暂不提供例子

原则:批量操作
分类:设计优化
备注:其实是业务逻辑优化的一个特例

原则:对输入进行缓存
分类:设计优化,缓存
范例:依靠CPU Cache/阵列Cache/磁盘Cache/磁盘/操作系统Cache/程序管理的Cache/专用Cache服务器等,对输入进行缓存,以加快速度

原则:对中间结果进行缓存
分类:设计优化,缓存
范例:预装载/索引/suffix tree

原则:对输出进行缓存
分类:设计优化,缓存
范例:使用buffer批量输出(匹配软件计算速度和设备的速度)

原则:空间换时间
分类:设计优化
范例:在DB中使用denormalized data
备注:这是一个比较通用的原则,Cache也是空间换时间。

原则:使用内存池
分类:设计优化,内存

原则:使用更好/更合适的GC算法
分类:设计优化,内存

原则:控制内存交换
分类:设计优化,内存

原则:吸收掉不必要的界面更新
分类:设计优化,GUI

原则:只重绘更新的区域
分类:设计优化,GUI

原则:对可视化的结果进行缓存
分类:设计优化,GUI
备注:中间结果缓存的一个特例

原则:parallelism–利用多CPU/多核心
分类:设计优化,并行

原则:利用并发(concurrency)
分类:设计优化,并行
提示:在单CPU上跑并发也能提高性能
范例:线程池

原则:选取合适的锁类型
分类:设计优化,并行,锁
范例:使用读写锁

原则:使用消息
分类:设计优化,并行,锁
备注:可以减少共享数据和锁

原则:使用异步模型
分类:设计优化,并行,锁
范例:使用epoll/kqueue等;nginx

原则:消除锁
分类:设计优化,并行,锁
提示:试用无锁的算法/数据结构/算法

原则:使用FP Paradigm
分类:设计优化,并行
提示:彪悍的FP不需要提示

算法优化

(其实算法往往是包含在设计中的)

原则:使用更优的算法,减小算法的阶
分类:算法优化
范例:使用BM/Sunday算法代替BF算法

原则:减小算法的常量(BigOO)
分类:算法优化
范例:使用sentry来编写double link list

原则:处理好Big Omega和BigO,使算法在“最坏的时候也不要太坏”
分类:算法优化
范例:quick sort,避免O(N*N)的情况

原则:使用更优的数据结构
分类:算法优化
范例:AVL Tree–>Hash Table–>Ternary Search Tree
备注:其实有些重复,主要是为了区分狭义的“算法”和“数据结构”

原则:寻找并行化算法
分类:算法优化
备注:和前面的parallelism有些重复,这个更多的是指可并行的算法而不是其它意义上的并行

小技巧

原则:编译器优化
分类:小技巧
范例:使用Intel的编译器,使用Intel的性能库IPP
备注:注意Proebsting定律

原则:树递归–>尾递归
分类:小技巧
备注:在许多语言中,尾递归是不需要栈的,自动转换成迭代了(例如在erlang中用尾递归实现无限循环)

原则:少用小技巧,以免妨碍大粒度上的性能优化
分类:小技巧
提示:主要是指那些影响并行计算的小技巧,或者那些没有使用profiler进行测量就草率进行的盲目优化

原则:远离“神话”
分类:小技巧
提示:有些流传的关于优化的神化不足信,“是骡子是马拉出来骝骝”,一切在profiler下见真章
范例:比如“大块内存分配非常慢”的神话(甚至有过一个人估计数量级的时候说:分配10M内存至少要1秒钟),比如“虚函数导致效率低”的神话,比如“解释运行比编译慢”的神话,等等

原则:使用Lazy Evaluation
分类:小技巧

原则:避免大对象复制
分类:小技巧
范例:RVO/RVal Ref

原则:预译码/编译成本地代码
分类:小技巧,解释器和VM
范例:PYC/HipHop

原则:混合使用各有优势的语言
分类:小技巧
范例:C里使用汇编;Python里使用C模块;

原则:使用二进制优化器
分类:小技巧
范例:JIT就是最出名的一种二进制优化;Win32SDK的BitBlt()函数也是;

……

重温:无论尝试了何种优化,都要使用profiler来测量这种优化
分类:红宝书
提示:时刻记心间

优化程序性能总结

性能优化有三个层次: 系统层次 算法层次 代码层次 系统层次关注系统的控制流程和数据流程,优化主要考虑如何减少消息传递的个数;如何使系统的负载更加均衡;如何充分利用硬件的性能和设施;如何减少系...
  • u013240812
  • u013240812
  • 2015年10月23日 14:34
  • 2619

第五章 优化程序性能

写程序的最主要目标就是使它在所有可能的情况下都正确工作。 程序员必须写出“清晰简洁”的代码,读懂、理解、修改   代码。        编写高效程序: 1.          选择合适的算法和数据结构...
  • yvhqbat
  • yvhqbat
  • 2015年10月11日 11:45
  • 651

优化程序性能 计算机系统结构 深入理解计算机系统

优化程序性能 1编写高效程序:合适的数据结构和算法,编译器能够有效优化以转换为高效可执行代码的 源码,对处理量特别大的计算将任务分为多个部分; 程序优化:消除不必要的内容(函数调用,条件测试,存...
  • u013240812
  • u013240812
  • 2015年10月23日 14:33
  • 719

程序性能优化-深入理解计算机系统

转自http://blog.sina.com.cn/s/blog_7572b5e50101qeja.html 1.对寄存器的访问的优化 寄存器访问优化的核心是尽量避免打断流水线. a...
  • le119126
  • le119126
  • 2015年04月23日 21:10
  • 628

C++程序常见的性能调优方式

转载自:http://www.708luo.com/?p=36 冗余的变量拷贝 相对C而言,写C++代码经常一不小心就会引入一些临时变量,比如函数实参、函数返回值。在临时变量之外,也会有其他一些情...
  • sole_cc
  • sole_cc
  • 2015年07月06日 20:22
  • 939

Java程序性能优化——性能调优层次

为了提升系统性能,开发人员可以从系统的各个角度和层次对系统进行优化。除了最常见的代码优化外,在软件架构上、JVM虚拟机层、数据库以及操作系统层都可以通过各种手段进行调优,从而在整体上提升系统的性能。设...
  • ma_hoking
  • ma_hoking
  • 2015年04月23日 22:04
  • 1394

【设计优化】-使用缓存(Cache)提高程序性能

缓存(Cache)就是一块用来存放数据的内存空间。主要作用是暂存数据处理结果,并提供下次访问使用。 缓存的使用非常普遍,比如,浏览器都会在本地缓存页面,从而减少HTTP 的访问次数。又...
  • zq602316498
  • zq602316498
  • 2014年09月06日 17:50
  • 2001

Linux应用程序性能优化教程

1.1   参考资料 《嵌入式Linux性能详解》,史子旺 https://perf.wiki.kernel.org/index.php/Main_Page,per...
  • kelsel
  • kelsel
  • 2016年10月08日 16:55
  • 383

C#程序性能优化

程序中我们每一丝动作都会加大程序运行的负担,当刚开始学习程序的时候常常不会去考虑程序运行的效率,大多数情况是为了实现功能,只要功能达到我想要的那么就算是达成了此项目标。当大部分功能的编码实现对我们来说...
  • Scalzdp
  • Scalzdp
  • 2014年06月25日 11:55
  • 2713

ABAP程序性能优化的一些做法(应该用那些优秀的写法)

待定
  • zzj_rainbow
  • zzj_rainbow
  • 2013年11月08日 18:58
  • 2834
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:程序性能优化
举报原因:
原因补充:

(最多只允许输入30个字)