当前位置:网站首页>数据库连接池HikariCP中的FastList快在哪里
数据库连接池HikariCP中的FastList快在哪里
2022-04-22 19:10:00 【有梦想的攻城狮】
背景
现在非常流行的一款数据库连接池工具HikariCP经常会出现在我们的日常工作中,这块工具的最大特点就是快,它在提高提升速度方面做了非常多的努力,其中的一项就是通过自己实现的FastList来代替了Java中自带的ArrayList来对部分数据进行处理,那我们这个地方就会有一个问题,FastList到底快在哪里呢?带着这个疑问,我们来看一下FastList的源码,看看它到底做了那些优化。
版本信息
我当前查看的POM文件的版本是5.0.2-SNAPSHOT
源码解读
在FastList类的最上面,有一行最明显的注释:Fast list without range checking. 这一句就非常直白的说明了它和ArrayList最大的一个区别:没有范围检查;下面我们来详细的看一下这个它的每个方法的一些
初始化
FastList中的数据默认是存在一个叫elementData的数组中,默认情况首次初始化32个数组空间,也可以通过传参来自定义指定的个数,对应的方法是:
public FastList(Class<?> clazz)
public FastList(Class<?> clazz, int capacity)
添加
FastList采用的是尾插法,即默认在数组的尾部插入新的元素,
public boolean add(T element)
{
//判断数组的长度是否小于当前已存入元素的个数,如果小于的,则表示数组还有空间来存放新的元素,直接在数组的已经存入的元素的后面增加新的元素
if (size < elementData.length) {
elementData[size++] = element;
} else {
//数据空间已满
//保存过去数组的长度
final var oldCapacity = elementData.length;
//新的数组长度为旧的数组长度左移1位,等同于 oldCapacity * 2,移位运算对于计算机处理起来效率更高
final var newCapacity = oldCapacity << 1;
//重新申请新长度的空数组
final var newElementData = (T[]) Array.newInstance(clazz, newCapacity);
//将过去的元素拷贝到新的数组当中
System.arraycopy(elementData, 0, newElementData, 0, oldCapacity);
//将该次添加的新元素存入新数组中现有元素的尾部
newElementData[size++] = element;
//将对象的数组替换成新申请的数组
elementData = newElementData;
}
return true;
}
获取指定下标元素
获取指定下标的元素在获取前没有范围检查,直接返回指定下标的数组元素,当然这样如果下标的范围超出了数组的范围的话,会抛出ArrayIndexOutOfBounds异常,在频繁的获取元素的过程中,默认是正确的也是一种非常不错的处理方案,当然还有一方面原因是这个类是开发者在当前的项目中在使用的,他在使用前会通过各种方式来保证查询的下标是正确的,这应该是开发者这样写的原因吧
public T get(int index)
{
return elementData[index];
}
移除最后一个元素
该方法没有判断集合中元素的个数,直接将最后一个元素赋值为null,如果本来集合就是空的话,那么size是等于0的,–size将出现ArrayIndexOutOfBounds异常,正常的情况是将最后一个元素取出,然后将集合中的最后一个元素赋值为空,然后将最后一个元素的返回
public T removeLast()
{
T element = elementData[--size];
elementData[size] = null;
return element;
}
移除指定的元素
按照从后往前的顺序逐个比较每一个元素与指定的元素是否相等,相等则将该元素下标后的所有元素向前复制一遍,将原来的最后一个元素赋值为null,该处有一个细节,两个对象比较不是用的equals方法,而是用的 == ,对于两个对象相比的话相当于是在比较他们的对象引用地址。
public boolean remove(Object element)
{
for (var index = size - 1; index >= 0; index--) {
if (element == elementData[index]) {
final var numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
return true;
}
}
return false;
}
清空
将集合中的每个元素设置为null
public void clear()
{
for (var i = 0; i < size; i++) {
elementData[i] = null;
}
size = 0;
}
插入元素到指定下标
public T set(int index, T element)
{
T old = elementData[index];
elementData[index] = element;
return old;
}
删除指定下标元素
删除指定下标的元素,为了更加快的处理速度,没有对下标和数组的范围进行比较,可能会出现ArrayIndexOutOfBounds的异常,如果指定下标的的元素存在,则将该下标后面的元素向前拷贝一位,然后将最后一个元素赋值为null,并且返回被删除的元素
public T remove(int index)
{
if (size == 0) {
return null;
}
final T old = elementData[index];
final var numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
return old;
}
其它方法
其它的还有很多方法在FastList中是没有进行支持的,因为在HikariCP中并没有用到这些方法
小拓展
在这个代码里面有很多地方用到了 –size 和 size++ 这样两种不同的写法,我们在使用的时候一定注意这两种不同写法所代表的含义,这样才能保证代码与你期望的效果一致,下面来简单说一下 –size 和 size– 这两种写法的区别
-
–size : 先对size进行 -1 的操作,然后再使用size对应的值
-
size-- : 先使用size,在对size进行 -1 的操作
下面来在实际使用场景中看一下
int k = 1;
//该打印语句打印出的是1
System.out.println(k--);
//该打印语句打印出的是0;
System.out.println(k);
int m = 1;
//该打印语句打印出的是0
System.out.println(--m);
//该打印语句打印出的是0;
System.out.println(m);
结语
HikariCP为了达到更快的速度,做了非常多的优化和非常细节的处理,FastList这个类只是其中的一个优化点,希望上面的梳理对大家深入的了解HikariCP这个数据库连接池可以提供一些帮助
版权声明
本文为[有梦想的攻城狮]所创,转载请带上原文链接,感谢
https://zhangzehai.blog.csdn.net/article/details/124340508
边栏推荐
- Introduction to ribbon of microservice load balancer
- [best practice] patrol item: turn on URL authentication in content distribution network (CDN)
- The function of final and why string is immutable
- HMS Core Discovery第14期回顾长文|纵享丝滑剪辑,释放视频创作力
- [spark] (task6) spark RDD completes the statistical logic
- @RequestBody修饰的对象属性大小写映射问题
- [appium stepping pit] failed to capture a screenshot Does the current view have ‘secure‘ flag set?
- C#与 Halcon 联合编程
- webrtc+turn+peerconnection_ Server measurement delay
- 防火门可以根据EN 1634-1 标准测试吗?
猜你喜欢

ArrayList learning notes

MCU infrared module knowledge sharing theory is the basis of practical combat in the future

Bluetooth shield / cervical massage instrument / mini charger / probe thermometer, segment code LCD display driver ic-vk1088b qfn32 4 * 4 ultra small volume, 22seg * 4com, and can enter the power savi

漂亮舒服的KN95口罩,防护能力也很强

原来,这才是开发者打开世界读书日的正确姿势

单片机红外模块知识分享,理论是日后实战的基础

WebRTC:Mesh/MCU/SFU三种通信架构

Detailed explanation of transfer method

项目实训- 基于unity的2D多人乱斗闯关游戏设计与开发(小地图工作前期知识:摄像机)

Redis缓存之String的滥用
随机推荐
webrtc+turn+peerconnection_server测延时
Flink窗口的类型
微服务调用组件Feign介绍
爱可可AI前沿推介 (4.22)
Pycharm 配置 Conda,国内使用正确的镜像源地址
[TCP] TCP three handshakes and four waves
System Analyst - paper writing framework construction
[best practice] patrol item: turn on URL authentication in content distribution network (CDN)
项目实训- 基于unity的2D多人乱斗闯关游戏设计与开发(小地图修改完善)
系统分析师-论文写作 框架搭建
How to build the campus running platform?
Linux环境下部署redis教程详解
Line by line interpretation of redet code
Project training - Design and development of 2D multiplayer scuffle game based on unity (small map modified and improved)
Misuse of redis cache string
【自我救赎--牛客网Top101 4天刷题计划】 第一天 热身运动
单片机红外模块知识分享,理论是日后实战的基础
What happens when you run the NPM install command?
Cvpr2022 𞓜 collaborative dual stream visual language pre training model for cross modal retrieval
C # joint programming with Halcon