您的位置:首页 > 其它

【程序设计实践】第7章 性能

2013-08-07 08:34 267 查看
第7章 性能
优化的第一要义是不做。程序是不是已经足够好了?应该了解程序将如何使用以及它将要运行于其中的环境,把它搞得更快有什么益处吗?
什么时候我们应该试图去加速一个程序?我们该如何做,又能够期望得到些什么呢?
最好的策略是使用那些能适应工作需要的、最简单最清晰的算法和数据结构,然后再度量其性能,看看是否需要做什么改变。打开编译系统的选择项,生成尽可能快的代码,考虑对程序本身做什么改变才能有最大作用,一次做一个改变并重新评价。这期间保留最简单的版本,以作为测试版本的对照无。

瓶颈

一旦程序已经足够快了,我们就停止,干嘛要没事找事呢?
必须弄清程序的瓶颈在哪里,保证找对了地方。

计时和轮廓

自动计时测量。许多系统里都有这种命令,它们可用于测量一个程序到底用了多少时间。Unix系统里有关命令的名字是time。
使用轮廓程序。除了可靠的计时方法外,在性能分析中最重要的工具就是一种能产生轮廓文件的系统。轮廓文件是对程序在哪些地方消耗了时间的一种度量。在有些轮廓文件中列出了执行中调用的各个函数、各函数被调用的次数以及它们消耗的时间在整个执行中的百分比。另一些轮廓文件计算每个语句执行的次数。执行非常频繁的语句通常对总运行时间的贡献比较大,根本没执行的语句所指明的可能是些无用代码,或者是没有合理测试到的代码。
集中注意热点。当某一个函数单独成为一个瓶颈的主导因素时,那么就只有两条路可以走了:或是采用一种更好的算法来改进这个函数;或者直接删去这个函数,重写环绕它的程序部分。
画一个图。图形特别适合用来表现性能测量的情况,它可以很好地传达信息,例如参数改变的影响、算法和数据结构的比较,有时也能指出某些没有预料到的情况。

加速策略

使用更好的算法或数据结构。要使程序运行速度快,最重要的因素是算法与数据结构的选择,有效的算法和不那么有效的算法造成的差距是巨大的。
让编译程序做优化。有一种毫不费力的改变就可能产生明显的加速效果,那就是打开编译系统的所有优化开关。
调整代码。只要数据有足够的规模,算法的正确选择就会显示它的作用。进一步说,算法方面的改进是跨机器、跨系统和跨语言的。但是,如果已经选择了正确的算法,程序的速度仍然是问题的话,下一步还能做的就是调整代码,整理循环和表达式的细节,设法使事情做得更快些。
不要优化那些无关紧要的东西。有时所做的代码调整毫无作用,这就是因为用到了一些不能产生差异的地方。

代码调整

收集公共表达式。如果一个代价昂贵的计算多次出现,那么就只在一个地方做它,并记录计算的结果。
用低代价操作代替高代价的。术语降低强度指的是用低代价操作代替高代价操作的那些优化。处罚和求余数比乘法慢得多,指针代替数组下标,简单计算代替函数。
铺开或者删除代码。循环的准备和运行都需要一定的开销。如果循环体本身非常小,循环次数很少,有一个更有效的方法,就是把它重写为一个重复进行的计算序列。
高速缓存频繁使用的值。以缓冲方式保存的值无须重新计算。缓存的价值来自于局部性。
写专用的存储分配程序。经常可以看到这种情况,程序里的惟一热点就是存储分配,表现为对malloc和free的大量调用。如果程序中需要的经常是同样大小的存储块,采用一个特定用途的存储分配器取代一般的分配器,有可能使速度得到实质性提高。这种特定的存储分配器调用malloc一次,取得基本存储块的一个大数组,在随后需要时一次送出去一块,这是一个代价很低的操作。释放后的存储块接在一个自由表的最后,这使它们可以立即重新投入使用。
对输入输出做缓冲。缓冲方式使数据传输操作以成批的方式完成,这能使频繁操作所造成的负担减到最小,并使代价昂贵的操作只在不可避免时才进行,使这种操作的代价能分散到许多数据值上。
特殊情况特殊处理。通过使用特殊代码去操作同样大小的对象,特殊用途的分配器可以比通用分配器节约时间和空间开销,还可能减少碎片问题。
预先算出某些值。有时可以让程序预先计算出一些值,需要时拿起来就用,这也可能使程序运行得更快些。
使用近似值。如果精度不太重要,那么就尽量使用具有较低精度的数据类型。
在某个低级语言里重写代码。低级语言程序的效率可能更高,不过这样做也要付出代价,那就是程序员的时间。

空间效率

使用尽可能小的数据类型以节约存储。提高空间效率的一个步骤是做些小修改,使现有存储能使用得更好,例如使用能满足工作需要的最小数据类型。缩小空间缝隙。
不存储容易重算的东西。时间换空间。与代码调整类似,这方面的修改也不太重要。最重要的改进应该是来自好的数据结构,或许还要伴随着算法的修改。

估计

要预先估计一个程序能运行得多么快,通常是非常困难的,而要估计某个特殊程序语句或者机器指令的时间代价,那就是双倍的困难了。然而,为一个语言或者系统做一次代价模拟却是比较简单的,它至少能使你对各种重要操作花费的时间有一个粗略的概念。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  程序设计