提高性能最怕是没有方向,没有头绪的时候不妨试试三件套:并行、异步、加缓存。

并行

并行比较容易理解,一个人做不完的事,多喊几个人一起做。从算法的角度,“并行”相当于“分治”。

早期 CPU 是单核的,后来单核性能提高不了,就采用多核;早期单进程、单线程,后期用多进程、多线程;早期单台机器,后来多机分布式。这些可以说都是“并行”的思想。所以如果某个逻辑实在难以提高的时候,可以考虑“并行”来处理。

当然,并行也会引入新的问题,最常见的就是同步问题,不论是单机上的多线程,还是多机之间的数据同步,都是程序员很头疼的问题。还有就是数据之间的拷贝和汇总,也都需要额外的开销。因此引入并行的得与失,需要具体问题具体分析(其实任何策略都需要)。

异步

“异步”和“缓存”都可以看作是 2/8 定理的延伸。也就是说 20% 的内容,虽然占少数,却是最重要的,而剩余的 80% ,虽然占多数,却是次要的。那么“异步”就是说当前有更重要的事要做,其它的不那么重要的可以在后台慢慢做,做完了我再处理。

例如现在几乎所有的网站都用 AJAX 来异步加载资源。换句话说,当用户打开一个网页时,它想要看到“主页面”的内容,因此这些内容是最重要的。而另外一些内容,例如对话框的内容和样式,在用户做一些操作之前,都是用不到的。因此我们可以异步加载对话框需要的资源,而把主要的精力放在加载和渲染“主页面”。

而在后端也有类似的场景。例如写数据库,一般情况下我们可能并不急着用写入的结果,那么“等待写入完成”就是一个次要的事情,因此可以异步执行写入操作,而先执行一些更重要的操作。

在现实生活中其实也类似,例如烧水,我们不急着喝就不需要等着它,可以先做一些其它的事,等用空时再查看水烧开没有。

当然,异步在某种程度上要求“并行”,需要异步进行的操作一般不能占用计算资源,例如或 IO 操作。或者需要指定其它的计算资源,例如用其它的机器执行计算。

异步也会极大增加编程的难度,想必不需要我多说吧。如果你觉得还行,那么考虑下异步加上并行吧。

加缓存

“异步”可以认为是 2/8 定理在“计算”上的应用,那么缓存就是 2/8 定理在“数据”上的应用。即数据的重要程度是不同的,总有一些数据会被频繁地访问,而另一些数据则基本无人问津。

缓存已经被大量应用。在计算机的组成中,就有一级缓存、二级缓存、内存到硬盘这样的层级存储结构,一级缓存速度最快但容量小,硬盘容量大但速度慢;在代码中我们也会用 HashMap 来自己做一些缓存;在高并发的压力之下,人们也发明了像 redis 等的快速缓存。

因此,如果发现数据访问速度是瓶颈时,可以考虑加缓存。当然,缓存的管理也会很复杂,管理方式的不同也会从各种角度影响到缓存的效果。因此,用与不用,就是另一个故事了。

小结

架构嘛,都是 trade-off。这“三件套”更多是方法论角度上的指导。真实使用时如何权衡各种方法的利弊,就需要具体问题具体分析了。