性能优化原则和方法
作为一个程序员,性能优化是常有的事情,不管是桌面应用还是web应用,不管是前端还是后端,不管是单点应用还是分布式系统。本文从以下几个方面来思考这个问题:性能优化的一般性原则,性能优化的层次,性能优化的通用方法。
一、一般性原则
依据数据而不是凭空想象
这是性能优化的第一原则,当我们怀疑性能有问题的时候,应该通过测试、日志、profillig来分析出哪里有问题,有的放矢,而不是凭感觉、撞运气。一个系统有了性能问题,瓶颈有可能是CPU,有可能是内存,有可能是IO(磁盘IO,网络IO)等等
忌过早优化
忌过度优化
深入理解业务代码
性能优化是持久战
选择合适的衡量指标、测试用例、测试环境
二、性能优化的层次
按照我的理解可以分为需求阶段,设计阶段,实现阶段;越上层的阶段优化效果越明显,同时也更需要对业务、需求的深入理解。
需求阶段
不战而屈人之兵,善之善者也
程序员的需求可能来自PM、UI的业务需求(或者说是功能性需求),也可能来自Team Leader的需求。当我们拿到一个需求的时候,首先需要的是思考、讨论需求的合理性,而不是立刻去设计、去编码。
需求是为了解决某个问题,问题是本质,需求是解决问题的手段。那么需求是否能否真正的解决问题,程序员也得自己去思考,产品经理(特别是知道一点技术的产品经理)的某个需求可能只是某个问题的解决方案,他认为这个方法可以解决他的问题,于是把解决方案当成了需求,而不是真正的问题。
需求讨论的前提对业务的深入了解,如果不了解业务,根本没法讨论。即使需求已经实现了,当我们发现有性能问题的时候,首先也可以从需求出发。
需求分析对性能优化有什么帮助呢,第一,为了达到同样的目的,解决同样问题,也许可以有性能更优(消耗更小)的办法。这种优化是无损的,即不改变需求本质的同时,又能达到性能优化的效果;第二种情况,有损的优化,即在不明显影响用户的体验,稍微修改需求、放宽条件,就能大大解决性能问题。PM退步一小步,程序前进一大步。
需求讨论也有助于设计时更具扩展性,应对未来的需求变化,这里按下不表。
设计阶段
高手都是花80%时间思考,20%时间实现;新手写起代码来很快,但后面是无穷无尽的修bug
设计的概念很宽泛,包括架构设计、技术选型、接口设计等等。架构设计约束了系统的扩展、技术选型决定了代码实现。编程语言、框架都是工具,不同的系统、业务需要选择适当的工具集。如果设计的时候做的不够好,那么后面就很难优化,甚至需要推到重来。
实现阶段
实现是把功能翻译成代码的过程,这个层面的优化,主要是针对一个调用流程,一个函数,一段代码的优化。各种profile工具也主要是在这个阶段生效。除了静态的代码的优化,还有编译时优化,运行时优化。后二者要求就很高了,程序员可控性较弱。
代码层面,造成性能瓶颈的原因通常是高频调用的函数、或者单次消耗非常高的函数、或者二者的结合。
下面介绍针对设计阶段与实现阶段的优化手段。
三、一般性方法
缓存
缓存的本质是加速访问,访问的数据要么是其他数据的副本 -- 让数据离用户更近;要么是之前的计算结果 -- 避免重复计算。缓存需要用空间换时间,在缓存空间有限的情况下,需要优秀的置换换算来保证缓存有较高的命中率。
缓存类型
文件缓存
数据缓存
计算结果缓存
并发
CDN缓存、多节点、http2.0
惰性
讲计算、加载推迟到需要的时候。如图片懒加载、路由懒加载等
批量、合并
更高效实现
缩小解空间
四、总结
参考:
Last updated
Was this helpful?