HikariCP为什么这么快?
#代码量非常小
要知道对于连接池来讲,代码越少,占用cpu和内存越少,Bug出现几率也是越小,那么代表他的执行率高,这就是为什么HikariCP受欢迎的原因之一
#稳定性,可靠性强
HikariCP是经受了市场的考验,走过太上老君的丹炉,现如今拿到SpringBoot的入场证, 走上了人生巅峰.
#速度奇快
光有健壮性可不行,坦克很健壮,却跑不过飞机,但是HikariCP却依靠自己的代码少,重写数据结构等特点,成功晋级速度最快连接池冠军宝座.
速度快的原因:
优化并精简字节码
使用FastList替代ArrayList
ConcurrentBag:更好的并发集合类实现
优化并精简字节码:
HikariCP在优化并精简字节码上也下了功夫, 使用第三方的Java字节码修改类库Javassist来生成委托实现动态代理。动态代理的实现在ProxyFactory类, 速度更快, 相比于JDK Proxy生成的字节码更少,精简了很多不必要的字节码。
使用FastList代替ArrayList:
FastList源码:
/**
* 没有列表检查的 FastList。
*
* @author Brett Wooldridge
*/
public final class FastList<T> implements List<T>, RandomAccess, Serializable
{private static final long serialVersionUID = -4598088075242913858L;private final Class<?> clazz;private T[] elementData;private int size;/*** 构建一个默认大小为32的列表。* @param clazz the Class stored in the collection*/@SuppressWarnings("unchecked")public FastList(Class<?> clazz){this.elementData = (T[]) Array.newInstance(clazz, 32);this.clazz = clazz;}/*** 构造具有指定大小的列表。* @param clazz the Class stored in the collection* @param capacity the initial size of the FastList*/@SuppressWarnings("unchecked")public FastList(Class<?> clazz, int capacity){this.elementData = (T[]) Array.newInstance(clazz, capacity);this.clazz = clazz;}
可以注意到:一是没有列表检查,而是默认构建一个大小为32的数组;
add源码:
@Overridepublic boolean add(T element){//给 list添加属性//如果 size值小于 初始化的值if (size < elementData.length) {elementData[size++] = element;}else {// 溢出的代码//elementData 原始32不够用 需要扩容final int oldCapacity = elementData.length;final int newCapacity = oldCapacity << 1;@SuppressWarnings("unchecked")//扩容集合final T[] newElementData = (T[]) Array.newInstance(clazz, newCapacity);//数组复制System.arraycopy(elementData, 0, newElementData, 0, oldCapacity);//属性赋值newElementData[size++] = element;elementData = newElementData;}return true;}
get源码:(既然不用ArrayList,那就与它做下对比)
// FastList:@Overridepublic T get(int index){return elementData[index];}// ArrayListpublic E get(int index) {rangeCheck(index);return elementData(index);}//可以看到ArrayList多出了rangeCheck 检查角标范围 节省时间
ArrayList操作get的时候,每次都要去检查一遍数组角标,而FastList却不需要去检查,进而速度更快.
delete源码:
// FastList:@Overridepublic boolean remove(Object element){for (int index = size - 1; index >= 0; index--) {if (element == elementData[index]) {final int numMoved = size - index - 1;//如果角标不是最后一个 copy一个新的数组结构if (numMoved > 0) {System.arraycopy(elementData, index + 1, elementData, index, numMoved);}//如果角标是最后面的 直接初始化为nullelementData[--size] = null;return true;}}return false;}// ArrayList:rangeCheck(index);modCount++;E oldValue = elementData(index);//FastList 少了检查范围 和 从头到尾的 检查元素动作 性能更快
对于remove方法,ArrayList不但先进行检查角标范围, 而且还从头到脚进行扫描元素, FastList摒弃了这个做法去追求性能上的极致.