程序性能优化策略

来源:互联网 发布:video.js 播放flv 编辑:程序博客网 时间:2024/06/05 21:01

列举几点常见的性能优化策略。

n 用空间换时间。该策略属于系统架构层面的优化。我们知道,各种缓存机制,从CPU L1/L2/RAM到硬盘,都可以通过空间换时间的策略。这类策略基本上是通过采用把计算的过程一步一步地保存或者缓存等方式,避免重复计算的发生。具体的方式可以采用数据缓冲、CDN等。类似的策略还表现为诸如冗余数据,比如数据镜像、负载均衡等。

n 用时间换空间。该策略也属于系统架构层面的优化。有时候使用少量的空间,可能性能会更好。比如网络传输,如果有一些压缩数据的算法,例如Huffman编码压缩算法[1],该算法本身运行过程其实很耗时,但是因为整体来看性能瓶颈在网络传输部分,所以用时间来换空间反而能省时间。

n 简化代码。该策略属于基础技术层面的优化。最高效的程序就是不执行任何代码的程序,所以,大多数情况下我们可以认为代码越少性能就越高。关于代码级优化的技术,大学的教科书中有很多示例了。比如,减少循环的层数、减少递归、在循环中少声明变量、少做分配和释放内存的操作、尽量把循环体内的表达式抽到循环外、条件表达式中的多个条件判断的次序、尽量在程序启动时把一些东西准备好、注意函数调用的开销(栈上开销)、注意面向对象语言中临时对象的开销、小心使用异常(不要用异常来检查一些可接受可忽略并经常发生的错误),等。这类知识需要我们非常了解编程语言和常用的语言自带资源库。从根本上来讲,不一定越少的代码越好,我们需要了解Java本地库的实现原理,例如同步问题,如果单纯采用同步锁(Synchronized)的方式,代码确实很少,但是实际的性能并不好,当大量线程同时访问代码块时,它会生成大量的锁,导致系统内部代码块互相等待,具体我们会在第5章详细介绍。所以,我们还是要有一定技术基础之后才能做到代码上的简化。

n 并行处理。该策略属于一种综合性策略。试想,如果CPU只有一个核,你要是还采用多进程、多线程的方式编写代码,那么计算密集型需求的应用程序反而会更慢,这是由巨大的操作系统调度和切换开销所导致的,这类型优化策略只能依靠多核CPU才能真正体现出多进程多线程的优势。实际应用过程中,我们会针对不同CPU进行大量高并发、密集型任务测试,不一定核数多就一定是最佳选择,也有些情况需要单核能力强的CPU,然后采用资源隔离技术对CPU核上的计算资源进行切分,把应用程序线程部署到不同的隔离区域,这样可以保证更多的并行程序同步进行,这也与整个系统的架构、内存共享策略、任务调度机制等多方面因素相关联。并行处理需要我们的程序拥有扩展性,不能水平或垂直扩展的程序无法进行并行处理。

综上所述,我们把经典的二八原则[2]移植到性能优化上来看,如图1-2所示,统计学认为,20%的系统设计或程序代码消耗了80%的系统性能。如果我们可以找到那20%的缺陷设计或者劣质代码,那么我们就可以较为容易地优化、解决80%的性能问题。



[1]    一种经典的压缩算法。于1952年问世,迄今为止仍经久不衰,广泛应用于各种数据压缩技术中,且仍不失为熵编码中的最佳编码方法,deflate等压缩算法也结合了huffman算法。

[2]    即巴莱多定律,是19世纪末20世纪初意大利经济学家巴莱多发现的。他认为,在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%尽管是多数,却是次要的,因此又称二八定律。列举几点常见的性能优化策略。

n 用空间换时间。该策略属于系统架构层面的优化。我们知道,各种缓存机制,从CPU L1/L2/RAM到硬盘,都可以通过空间换时间的策略。这类策略基本上是通过采用把计算的过程一步一步地保存或者缓存等方式,避免重复计算的发生。具体的方式可以采用数据缓冲、CDN等。类似的策略还表现为诸如冗余数据,比如数据镜像、负载均衡等。

n 用时间换空间。该策略也属于系统架构层面的优化。有时候使用少量的空间,可能性能会更好。比如网络传输,如果有一些压缩数据的算法,例如Huffman编码压缩算法[1],该算法本身运行过程其实很耗时,但是因为整体来看性能瓶颈在网络传输部分,所以用时间来换空间反而能省时间。

n 简化代码。该策略属于基础技术层面的优化。最高效的程序就是不执行任何代码的程序,所以,大多数情况下我们可以认为代码越少性能就越高。关于代码级优化的技术,大学的教科书中有很多示例了。比如,减少循环的层数、减少递归、在循环中少声明变量、少做分配和释放内存的操作、尽量把循环体内的表达式抽到循环外、条件表达式中的多个条件判断的次序、尽量在程序启动时把一些东西准备好、注意函数调用的开销(栈上开销)、注意面向对象语言中临时对象的开销、小心使用异常(不要用异常来检查一些可接受可忽略并经常发生的错误),等。这类知识需要我们非常了解编程语言和常用的语言自带资源库。从根本上来讲,不一定越少的代码越好,我们需要了解Java本地库的实现原理,例如同步问题,如果单纯采用同步锁(Synchronized)的方式,代码确实很少,但是实际的性能并不好,当大量线程同时访问代码块时,它会生成大量的锁,导致系统内部代码块互相等待,具体我们会在第5章详细介绍。所以,我们还是要有一定技术基础之后才能做到代码上的简化。

n 并行处理。该策略属于一种综合性策略。试想,如果CPU只有一个核,你要是还采用多进程、多线程的方式编写代码,那么计算密集型需求的应用程序反而会更慢,这是由巨大的操作系统调度和切换开销所导致的,这类型优化策略只能依靠多核CPU才能真正体现出多进程多线程的优势。实际应用过程中,我们会针对不同CPU进行大量高并发、密集型任务测试,不一定核数多就一定是最佳选择,也有些情况需要单核能力强的CPU,然后采用资源隔离技术对CPU核上的计算资源进行切分,把应用程序线程部署到不同的隔离区域,这样可以保证更多的并行程序同步进行,这也与整个系统的架构、内存共享策略、任务调度机制等多方面因素相关联。并行处理需要我们的程序拥有扩展性,不能水平或垂直扩展的程序无法进行并行处理。

综上所述,我们把经典的二八原则[2]移植到性能优化上来看,如图1-2所示,统计学认为,20%的系统设计或程序代码消耗了80%的系统性能。如果我们可以找到那20%的缺陷设计或者劣质代码,那么我们就可以较为容易地优化、解决80%的性能问题。



[1]    一种经典的压缩算法。于1952年问世,迄今为止仍经久不衰,广泛应用于各种数据压缩技术中,且仍不失为熵编码中的最佳编码方法,deflate等压缩算法也结合了huffman算法。

[2]    即巴莱多定律,是19世纪末20世纪初意大利经济学家巴莱多发现的。他认为,在任何一组东西中,最重要的只占其中一小部分,约20%,其余80%尽管是多数,却是次要的,因此又称二八定律。




欢迎关注麦克叔叔每晚十点说,让我们一起交流与学习。

原创粉丝点击