引言

之前参加中间件比赛,以及一些日常开发的经验,在这里总结了一些提升程序性能(qps/tps)的技巧,持续更新。一些只适用与比赛而不适合实际工程的技巧我会用斜体(only race)标注

1、减小锁的粒度

案例:

2、减小调度的粒度

传统的基于线程的调度模型调度粒度过大,往往导致频繁的上下文切换影响程序性能

案例:

3、避免伪共享

CPU的缓存都是以缓存行(通常为64B)为单位的,即使互相之间不需要同步的变量,只要位于同一个缓存行中,一个变量的改变也会导致整个CPU缓存的失效。

案例:

4、尽可能地重用对象,减少GC

案例:

5、数据多版本(使用快照)

案例:

6、将竞争分散

案例:

7、尽量不要使用库 (only race)

这一条只适用于竞赛的情况,在竞赛中的往往线上资源的CPU不是很充足,而库中往往包含大量的判断校验等逻辑,比较浪费CPU,所以我们应该尽量将库中的核心代码手工抽取出来进行调用。

注:这里的库包括JDK

8、Less is More

很多东西并不是越多越好,特别是那些会占用资源的东西。

案例(比赛中实测的一些结果):

9、不变模式

当一个对象不会再发生状态改变时,线程对这个对象的访问自然就不需要任何同步。

所以有一个技巧,当有多个线程尝试着访问同一个对象时,可以思考能否将这个对象拆成多份,并且其中有一些是只读的,这样只读的部分就可以应用不变模式,线程访问不需要任何同步操作。

案例:

10、线程亲和性

线程亲和性技术能够让开发人员将某个重要的线程直接绑定到某个CPU上面,保证这个重要的线程始终拥有CPU资源,不会因为时间片耗尽而被换出去。Java中有封装好的线程亲和性实现:https://github.com/OpenHFT/Java-Thread-Affinity