HikariCP Druid比较

HikariCP Github地址: https://github.com/brettwooldridge/HikariCP

HikariCP是数据库连接池,而且是号称史上最快的, SpringBoot2.0也已经采用HikariCP作为默认连接池配置.

HikariCP为什么这么快

1.1 代码量非常小:
要知道对于连接池来讲,代码越少,占用cpu和内存越少,Bug出现几率也是越小,那么代表他的执行率高,这就是为什么HikariCP受欢迎的原因之一
1.2 稳定性,可靠性强:
HikariCP是经受了市场的考验,走过太上老君的丹炉,现如今拿到SpringBoot的入场证,走上了人生巅峰.
1.3 速度奇快:
光有健壮性可不行,坦克很健壮,却跑不过飞机,但是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;
  }

@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;
   }
 /*
    * 我复制ArrayList的get代码 来看看为什么 FastList 更快
    *  public E get(int index) {
    *   rangeCheck(index);
    *    return elementData(index);
    *   }
    *   多出了rangeCheck 检查角标范围 节省时间
    */
   @Override
   public T get(int index)
   {
      return elementData[index];
   }
 /*
    * 这个是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;
   }

 

ArrayList不但先进行检查角标范围,而且还从头到脚进行扫描元素,而FastList的get和remove方法摈弃了这一做法。

HikariCP在优化并精简字节码上也下了功夫,使用第三方的Java字节码修改类库Javassist来生成委托实现动态代理.动态代理的实现在ProxyFactory类,速度更快,相比于JDK Proxy生成的字节码更少,精简了很多不必要的字节码.

posted @ 2019-04-25 17:13  跳刀不跳  阅读(10817)  评论(3编辑  收藏  举报