提交订单性能优化系列之004-测试hikari数据源


概括总结

使用hikari数据源之后,相对于第003版的druid数据源,从提交订单这个复杂的操作上来说,性能提升了17.79%。而从获取数据库连接这一简单的操作上来说,hikari比druid优秀几百倍

004版本更新说明

pom.xml文件中引入了新的jar包:

<!-- HikariCP数据库连接工具 -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>3.2.0</version>
</dependency>

HikariCP-3.2.0.jar包的大小是141KB,而003版本中的druid-1.1.10.jar包的大小是2693KB,甚至都不是一个数量级的。

这一版本写了两个测试类:Version004TestVersion004Test2。其中Version004Test用于测试提交订单的耗时情况,Version004Test2用于测试获取数据库连接的耗时情况。另外,由于hikari的性能好得超乎想像,毫秒这个单位已经太粗糙了,于是把Version004Test2中的时间单位改成了纳秒


测试结果

Version004Test的测试结果:

002版本(自己写的数据源)耗时(ms)003版本(druid数据源)耗时(ms)004版本(hikari数据库源)耗时(ms)
104712591035

003版本相对于002版本性能下降了: (1259 - 1047) / 1047 * 100% = 20.24%

004版本相对于003版本性能提升了: (1259 - 1035) / 1259 * 100% = 17.79%

004版本相对于002版本性能提升了: (1047 - 1035) / 1047 * 100% = 1.14%

Version004Test2的测试结果:
日志打印如下:

druid 获取一个数据库连接平均耗时:2392283 纳秒(获取连接后不关闭连接)
hikari 获取一个数据库连接平均耗时:3268791 纳秒(获取连接后不关闭连接)
druid 获取一个数据库连接平均耗时:1812491 纳秒(获取连接后不关闭连接)
hikari 获取一个数据库连接平均耗时:61716 纳秒(获取连接后不关闭连接)


druid 获取一个数据库连接平均耗时:1800770 纳秒(获取连接后关闭连接)
hikari 获取一个数据库连接平均耗时:2175 纳秒(获取连接后关闭连接)
druid 获取一个数据库连接平均耗时:1834128 纳秒(获取连接后关闭连接)
hikari 获取一个数据库连接平均耗时:2614 纳秒(获取连接后关闭连接)

可以总结为:如果获取连接后,不关闭连接,则druid和hikari在性能上是一个级别的。但是由于实际项目中,获取连接后都会关闭连接,这时候hikari的性能比druid优秀几百倍:1800770 / 2175 = 827.94 倍。

【备注】:不同的机器上的测试结果会不一样,以上测试结果仅供参考。


hikari为什么这么优秀?

HikariCP自己宣传的卖点是"zero-overhead",翻译成中文也就是"零开销"。但是要注意它是打了引号的,意思可以理解为:虽然不是真的零开销,但是跟其他的数据源工具比起来,可以认为是零开销了。这样的宣传我是可以接受的。

这可不像是druid那样明目张胆地吹牛皮说自己是Java语言中最好的数据库连接池,连引号都不打。这样的宣传我也是可以接受的,毕竟druid在github上的星星数量确实是比其他的数据源高很多。

话说回来,hikari为什么这么优秀呢?

官方的回答是这样的:“how we do it here

这个回答我在测试之前点进去过,一看是英文版的,马上关闭了。后来看到了Version004Test2的测试结果,又打开了那个页面,靠着有道词典一字一句地把文章看完了。总结起来有以下两点:

  1. ArrayList的优化:当从ArrayList中移除某个对象时,会从头到尾执行扫描,但是我们知道,数据库相关的对象有很多都是需要关闭的,关闭的顺序一般是与打开的顺序相反的,即最需要关闭的对象是保存在列表的尾部的,这意味着,如果能从尾到头来扫描的话,性能就会有提升。于是ArrayList就被自定义的FastList取代了

  2. 字节码层面的优化:对比一下以下两行代码的区别:

代码段1:(其中PROXY_FACTORY是类ProxyFactory的一个静态实例对象)

PROXY_FACTORY.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames));

代码段2:(其中ProxyFactory是一个类)

ProxyFactory.getProxyPreparedStatement(this, delegate.prepareStatement(sql, columnNames));

你能看出谁比谁的性能更高吗?反正我是看不出来。不过,虽然从java代码的层面看不出来,但是一旦编译成了字节码,区别就很明显了(第二种性能更好)。我在这里就不列举了,你可以去这里看看。

当然了,这两点只是样本例子,并不代表这个工具包中只做了这两点优化。特别是其中的第2点,能涵盖的范围非常广泛,真是让人佩服。


源码

004版本的github源码在这里,如果不知道怎样运行项目,请参考这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值