性能优化指南:性能优化的一般性原则与方法( 二 )


需求阶段
不战而屈人之兵是好人
程序员的需求可能来自 PM、UI 业务需求(或功能需求),也可能来自团队需求 。当我们得到一个需求时,我们首先需要思考和讨论需求的合理性,而不是立即设计和编码 。
需求就是解决问题,问题就是本质,需求就是解决问题的手段 。所以需求是否真的能解决问题,程序员就得自己去想了 。上一篇文章说过,一个产品经理(尤其是懂一点技术的产品经理)的某个需求,可能只是某个问题的解决方案,他认为会解决他的问题,对待解决方案作为一个要求,而不是一个真正的问题 。

性能优化指南:性能优化的一般性原则与方法

文章插图
需求讨论的前提是对业务的深入了解 。如果你不了解业务,你根本无法讨论它 。即使需求已经实现了,当我们发现有性能问题时,也可以先从需求开始 。
需求分析如何帮助性能优化?首先,为了达到同样的目的,解决同样的问题,可能会有性能更好(消耗更少)的方法 。这种优化是无损的,即在不改变需求本质的情况下,可以达到性能优化的效果;第二种情况,有损优化,即在不明显影响用户体验的情况下,稍微修改需求,放宽条件 。可以大大解决性能问题 。PM 后退了一小步,程序向前迈出了一大步 。
需求讨论还有助于在设计期间更具可扩展性并应对未来的需求变化,此处未列出 。
设计阶段
专家将 80% 的时间用于思考,20% 的时间用于实施;新手写代码非常快,但是有无穷无尽的错误修复
设计的概念非常广泛,包括架构设计、技术选型、界面设计等等 。架构设计约束了系统的扩展,技术选型决定了代码实现 。编程语言和框架都是工具,不同的系统和业务需要选择合适的工具集 。如果设计做得不够好,后期将难以优化,甚至需要推后 。
实现阶段
实现是将函数转换为代码的过程 。这一层的优化主要是针对一个调用过程、一个函数、一段代码的优化 。在这个阶段,各种工具也主要是有效的 。除了静态代码优化,还有编译时优化和运行时优化 。后两者要求很高,程序员的可控性较弱 。
在代码层面,造成性能瓶颈的原因通常是函数调用频繁,函数单次消耗非常高,或者两者兼而有之 。
下面介绍设计阶段和实施阶段的优化方法 。
一般的做法
缓存
没有缓存解决不了的性能问题 。如果有,则添加一级缓存
缓存 /k??/ KASH,[1] 是一个或那个数据,因此对于那个数据可以是 ; 缓存中的数据可能是 of an 或 of data。
缓存的本质是加快访问速度,访问的数据要么是其他数据的副本——让数据更贴近用户;或先前计算的结果 - 避免重复计算 。
缓存需要以空间换时间 。在缓存空间有限的情况下,需要出色的替换转换来保证缓存的高命中率 。
数据缓存
这是我们最常见的缓存形式,将数据缓存在离用户更近的地方 。比如操作系统中的CPU缓存和磁盘缓存 。对于一个web应用来说,前端会有一个浏览器缓存,一个CDN,以及一个反向代理提供的静态内容缓存;后端将有一个本地缓存和一个分布式缓存 。
数据缓存通常是设计考虑因素 。
对于数据缓存,需要考虑缓存一致性的问题 。对于分布式系统中具有强一致性要求的场景,可行的解决方案包括租约和版本号 。
计算结果缓存
对于消耗大量金钱的计算,可以将计算结果缓存起来,下次直接使用 。
我们知道,递归代码一个有效的优化方法就是缓存中间结果,table,避免重复计算 。里面的缓存就是这个想法 。