发布于 

Hutool MD5 Time Consuming

Hutool MD5 Time Consuming

本文介绍,使用Hutool该框架的一个小坑。就一行代码:MD5.create().digestHex()

具体的业务逻辑就不展开说了,发现这个坑,也是看到一位大佬的博客+自己实操出来的。

这些贴一下博客的连接:震惊,一行MD5居然让小伙伴都回不了家!!!

Introduce Service

你是否也有一些业务需要使用摘要算法。说到摘完算法:你的第一反应是否是MD5~~

摘要算法的具体介绍也不展开了,可以自己维基百科:维基百科-MD5

我们直接上代码:

StopWatch stopWatch = new StopWatch();

stopWatch.start("hutool");
String hutoolMd5Value = MD5.create().digestHex(noUserQto.toString());
stopWatch.stop();

stopWatch.start("guava");
HashCode hashCode = Hashing.md5().hashBytes(noUserQto.toString().getBytes());
String guavaMd5Value = hashCode.toString();
stopWatch.stop();

log.info(stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
log.info("testMd5,hutoolMd5Value:{},guavaMd5Value:{},r:{}", hutoolMd5Value, guavaMd5Value, guavaMd5Value.equals(hutoolMd5Value));

代码逻辑很简单,对一个对象做MD5摘要,我们通过StopWatch来统计耗时。

但是上面的耗时测试的不够严谨,更加专业的是要使用基准测试。

可以去考古我之前的文章,或者自己google下呢。

但是这里没有用基准测试来做,是因为,我只有项目启动的第一次调用:MD5.create().digestHex(),才有问题。

这里直接贴出结果:

2023-03-16 17:38:00.289 [INFO ] [main]   c.n.g.p.c.s.t.ArtTemplateRedis - StopWatch '': running time = 201 ms
---------------------------------------------
ms % Task name
---------------------------------------------
000000198 99% hutool
000000002 01% guava

2023-03-16 17:38:12.426 [INFO ] [main] c.n.g.p.c.s.t.ArtTemplateRedis - testMd5,hutoolMd5Value:71cf7926332d3355101be259e420f072,guavaMd5Value:71cf7926332d3355101be259e420f072,r:true

并且我运行了多次得到的结果。这里要特别说明下:我们是在第一次调用md5方法的时候,才会出现上面的问题。

我们通过运行结果可以看到:他们分别是不同的工具类,一个是国内大名鼎鼎的hutool,另外一个是国外著名的guava。

耗时不在一个数量级上面。但是我们第n次调用:MD5.create().digestHex(),性能是可以和guava的md5方法齐平的。

这里直接贴出结论:

image-20230316193815316

hutool的MD5.create()方法在第一次调用的时候,会触发BouncyCastleProvider#setup的初始化逻辑,加载一些加密算法逻辑。

Fix The Problem

到此我们清楚了耗时的问题。我们知道,hutool的md5工具类,在第一次调用的时候,耗时会比较长。

所以我们的解决方案有很多种。如果你项目很多地方都用了该方法:MD5.create().digestHex()

那我建议你在spring容器启动成功之后,调用一下该方法。就可以了,又或者你们项目能够接受这第一次请求200ms的性能损失。那改都不用改了,逃)

但是你如果想改彻底点。建议你换为guava的工具类。

到此,完结,撒花~~下班