-
HikariCP是什么
HikariCP是數據庫連接池,而且是號稱史上最快的,而且目前來看確實是這樣的,SpringBoot2.0也已經采用HikariCP作為默認連接池配置.
官網性能柱狀圖
HikariCP GitHub網址 -
HikariCP為什么這么快
1.1 代碼量非常小:
要知道對于連接池來講,代碼越少,占用cpu和內存越少,Bug出現幾率也是越小,那么代表他的執行率高,這就是為什么HikariCP受歡迎的原因之一
1.2 穩定性,可靠性強:
HikariCP是經受了市場的考驗,走過太上老君的丹爐,現如今拿到SpringBoot的入場證,走上了人生巔峰.
1.3 速度奇快:
光有健壯性可不行,坦克很健壯,卻跑不過飛機,但是HikariCP卻依靠自己的代碼少,重寫數據結構等特點,成功晉級速度最快連接池冠軍寶座. -
HikariCP為什么這么快呢
HikariCP快得益于:
1.1 優化并精簡字節碼
1.2 使用FastList替代ArrayList
1.3 ConcurrentBag:更好的并發集合類實現
下面,我帶大家看一下這么牛的連接池的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;
}
上面是FastList的構造,可以看到它初始化了32長度的數組
@Override
public 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和remove方法
/*
* 我復制ArrayList的get代碼 來看看為什么 FastList 更快
* public E get(int index) {
* rangeCheck(index);
* return elementData(index);
* }
* 多出了rangeCheck 檢查角標范圍 節省時間
*/
@Override
public T get(int index)
{
return elementData[index];
}
很明顯ArrayList操作get的時候,每次都要去檢查一遍數組角標,而FastList卻不需要去檢查,進而速度更快.
/*
* 這個是ArrayList的 remove()代碼 FastList 少了檢查范圍 和 從頭到尾的 檢查元素動作 性能更快
* rangeCheck(index);
* modCount++;
* E oldValue = elementData(index);
*/
@Override
public 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);
}
//如果角標是最后面的 直接初始化為null
elementData[--size] = null;
return true;
}
}
return false;
}
這個是remove方法,一樣的ArrayList不但先進行檢查角標范圍,而且還從頭到腳進行掃描元素,FastList摒棄了這個做法去追求性能上的極致.
HikariCP在優化并精簡字節碼上也下了功夫,使用第三方的Java字節碼修改類庫Javassist來生成委托實現動態代理.動態代理的實現在ProxyFactory類,速度更快,相比于JDK Proxy生成的字節碼更少,精簡了很多不必要的字節碼.