忧郁的大能猫
好奇的探索者,理性的思考者,踏实的行动者。
Table of Contents:
编程领域的优化技术
- 控件复用(避免频繁申请和释放内存)
- listview里面的item
- 屏幕外的 Item 不销毁,而是放入复用池
- 新 Item 需要显示时直接从池中获取。
- 线程池
- 对象池
- 数据库连接池
- 网络连接池
- 时间换空间
- 索引
- 优点:
- 大幅降低查询时间
- 缺点:
- 占用额外存储空间
- 更新数据时需要维护索引
- 缓存
- 把计算结果或热点数据保存起来,下次直接使用
- 存在缓存一致性问题
- 增加系统复杂度
- 局部性原理
- 下步执行指令的可能就在当前附近,下次访问的数据也可能就在当前的附近
- 预计算,预处理(Precompute)
- 提前计算未来可能使用的数据
- 数学查表法
- 并行处理
- 多进程
- 多线程
- GPU 替代 CPU
- 流水线技术
- 将任务拆分为多个阶段,各阶段并行工作。
- 视频编码
- CPU指令流水线
- 延迟加载(Lazy Loading):需要时再加载资源
- 图片懒加载
- 数据懒加载
- 批处理(Batch Processing)
- 核心思想:多个请求合并后统一处理。
- 典型场景:
- 数据库批量插入 1000次INSERT
- 网络包合并发送
- 日志写入
- 异步化(Asynchronous Processing)
- 核心思想:发起任务后立即返回,不阻塞当前流程。
- 典型场景:
- 消息队列
- 邮件发送
- 订单处理
- 优点:
- 提高系统响应速度
- 削峰填谷
- 算法与数据结构优化
- 核心思想:通过更高效的算法降低时间复杂度。
- 通常这是收益最高的一类优化。
- 通过预测提高性能
- 小说的下一页预加载
- 电商大促的CDN预热
从本质上看,大多数性能优化都可以归纳为四大方向:
1. 少创建
├── 控件复用
├── 线程池
└── 对象池
少计算
├── 缓存
├── 索引
├── 预计算
└── 更优算法
同时做
├── 多线程
├── 多进程
├── GPU计算
└── 流水线
少等待
├── 异步化
├── 批处理
└── 延迟加载
抽象
封装,隐藏实现细节
自顶向下逐步分解
以空间换时间
空间和时间局部性原理
面向摩尔定律的设计
由于摩尔定律,单芯片的集成度相对于设计开始时很容易翻一番甚至翻两番。计算机设计者必须预测其设计完成时的工艺水平,而不是设计开始时的。
比如google提供的免费gmail服务就是预测将来硬盘价格会大幅下降
使用抽象简化设计
使用抽象技术来表示不同的设计层次,在高层次中看不到低层次的细节,只能看到一个简化的模型。
例如计算机网络层次划分模型,软件开发SDK,API等无不体现出抽象的思想。
加速大概率事件
加速大概率事件(Common case fast)远比优化小概率时间更能提高性能。大概率事件通常比小概率事件简单,从而易于提高。大概率事件规则意味着设计者需要知道什么事件是经常发生的,这只有通过仔细的实验与评估才能得出。
例如:各种缓存(内存缓存、CDN缓存),索引等。
Amdahl定律(Amdahl’s law)
阐述提升一个系统的一个部分的性能对整个系统有多大影响。它是“收益递减定律”的量化版本。
通过并行提高性能
从计算机诞生开始,计算机设计者就通过并行执行操作来提高性能。
例如:多线程,并发编程调用等提升吞吐量。
通过流水线提高性能
现代的工厂里的生产线叫“流水线”。我们可以把装配 iPhone 这样的任务拆分成一个个细分的任务,让每个人都只需要处理一道工序,减少中间等待的环节,最大化整个工厂的生产效率。类似的,我们的 CPU 其实就是一个“运算工厂”。我们把 CPU 指令执行的过程进行拆分,细化运行,也是现代 CPU 在主频没有办法提升那么多的情况下,性能仍然可以得到提升的重要原因之一。
例如:一个大规模的SQL分成几个规模适当的小SQL进行执行、分布式系统、异步编程,分而治之,MapReduce,Fork/Join等。
通过预测提高性能
在某些情况下,如果假定从误预测恢复执行代价不高并且预测的准确率相对较高,则通过猜测的方式提前开始某些操作,要比等到确切知道这些操作应该启动时才开始要快一些。
例如:小说的下一页预加载,电商大促的CDN预热,空间换时间等。
存储器层次
程序员希望存储器速度更快,容量更大,价格更便宜。设计师们发现可以通过存储器层次(hierarchy of memory)来解决这些相互矛盾的需求。在存储器层次中,速度最快,容量最小并且每位价格最昂贵的存储器位于顶层,而速度最慢,容量最大且每位价格最便宜的存储器位于最底层。程序员看到的主存同时具有存储器层次中顶层的高速度和底层的大容量和便宜的特征。可以把存储器层次想象成一个堆叠的三角形,该形状表示速度/价格/和容量:越靠近顶端,存储器速度越快/每位价格越高:底层宽度越大,存储器容量越大。
通过冗余提高可靠性
计算机不仅需要速度快,还要工作可靠。由于任何一个物理器件都有可能失效,因此可以通过使用冗余部件的方式提高系统的可靠性(dependable),冗余部件可以替换失效部件。可以通过牵引式挂车来理解可靠性:牵引式挂车后轴两边具有双轮胎,在一个轮胎出问题时卡车仍然可以继续工作。(在一个轮胎出问题时,卡车司机立即直接开往修理厂进行修理,从而恢复冗余性。)
例如:冗余也可以提升性能,如数据库查询。