gpt4 book ai didi

java - Fast MD5 Library 是不是比 Java 7 MD5 更快?

转载 作者:行者123 更新时间:2023-11-29 09:35:43 24 4
gpt4 key购买 nike

所以我一直在寻找一种更快的方法来计算 MD5 校验和并遇到了 Fast MD5 library - 但是当我在我的机器上使用 Java 7 对其进行基准测试时,它比 Java 版本慢。

要么我在做一些愚蠢的事情(很可能),要么 Java 7 实现了更好的算法(也很可能)。这是我 super 简单的“基准”- 也许我今天没有喝足够的咖啡......

    MD5 digest = new MD5();
System.out.println(MD5.initNativeLibrary(true));
byte[] buff = IOUtils.readFully(new FileInputStream(new File("blahblah.bin")), 64000000, true);
ByteBuffer buffer = ByteBuffer.wrap(buff);
for (int j = 0; j < 100; j++) {
start = System.currentTimeMillis();
String md5Base64 = Utilities.getDigestBase64(buffer);
end = System.currentTimeMillis();
total = total + (end-start);
}
System.out.println("Took " + ((total)/100.00) + " ms. for " + buff.length+" bytes");
total = 0;
for (int i = 0; i < 100; i++) {
start = System.currentTimeMillis();
digest.Init();
digest.Update(buff);
digest.Final();
end = System.currentTimeMillis();
total = total + (end-start);
}
System.out.println("Took " + ((total)/100.00) + " ms. for " + buff.length+" bytes");

然后我得到:

Took 247.99 ms. for 64000000 bytes
Took 295.16 ms. for 64000000 bytes

根据评论,我一遍又一遍地运行 benchamrk,得到了最奇怪的结果。 FastMD5 计算保持不变,但 Java 7 版本变慢了。 ????

Took 246.54 ms. for 64000000 bytes
Took 294.69 ms. for 64000000 bytes
************************************
Took 540.55 ms. for 64000000 bytes
Took 292.69 ms. for 64000000 bytes
************************************
Took 537.07 ms. for 64000000 bytes
Took 292.12 ms. for 64000000 bytes

最佳答案

让我们先回答您问题的简单部分:

我认为当您再次运行代码时,您的 Java 7 执行时间大约翻倍,因为如果您只是将发布的代码放入 for 循环,您会忘记在执行之前将 total 重置为 0第 2、3、4、... Java 7 测试的运行(对于第一个,它可能从变量初始化中设置为 0)。

因此,通过简单地减去您未设置回 0 的偏移量来修复您的表格会得到:

Took 246.54 ms. for 64000000 bytes
Took 294.69 ms. for 64000000 bytes <---.
************************************ |
Took 245.86 ms. for 64000000 bytes (subtracting 294.69)
Took 292.69 ms. for 64000000 bytes <---.
************************************ |
Took 244.38 ms. for 64000000 bytes (subtracting 292.69)
Took 292.12 ms. for 64000000 bytes

现在,事情看起来非常一致,甚至显示了其他回复中提到的“JVM 预热”,而且它只产生了大约 1% 的差异。

现在,为什么 Java 7 的性能优于 FastMD5?

他们可能使用了一种更好的算法,该算法更适合 Java 编译器随后执行的优化。

例如,nio ByteBuffers 专门设计用于通过使用 DMA 等 native 事物来更快地访问内存。因此,MD5 的 Java 7 实现使用 ByteBuffer 而不是 byte[] 作为输入这一事实让我认为他们实际上正在利用这些功能(否则他们可能也只是采用了 byte[]。)

更进一步说,我们可能需要知道您的 Utilities 对象的确切功能,例如,然后比较 FastMD5 和 Java 实现的源代码。

但我要说:您的结果(给定 total=0 修复)对我来说非常有意义,您可能会享受这样一个事实,即您可以减少对外部库的依赖! ;)

顺便说一句:在 3.5GHz CPU 上,您看到的性能差异仅对应于每个处理数据字节大约 2-3 个 CPU 时钟周期(每个字节总共大约 15 个时钟周期)。因此,鉴于差异非常小,这很可能取决于所使用的确切平台和 JVM,两者中哪一个最终会更快。

添加

您的基准测试数字表明您可以使用这两个 MD5 实现处理大约 220-260MB/s,如果您查看 Google 搜索显示的其他声称的规范(例如“结果实现”下的 http://www.zorinaq.com/papers/md5-amd64.html),这听起来很合理。因此,与您收到的所有其他回复相反,我确实觉得我会相信您的数字。

如果您想更加确定,请改变 byte[] 的大小并查看由此产生的处理时间变化。如果一切正常,你会看到一个线性关系,你可以用这个函数来适应:

total/100.0 = m * buff.length + b           (your usual y = mx + b)

这里,m 是每个字节的处理时间,应该在 1/250MB/s = 4ns/byte 左右,b 是函数用来执行的设置时间初始化局部变量等,以及 System.currentTimeMillis(); 花费的时间。这个数字应该相当小(可能小于 1 毫秒)。

然后,要确定这两种算法中哪一种更适合您,您需要比较mb。如果您通常处理小型数据数组,b 可能会比 m 更重要地确定哪种算法更好,而对于大型数据集,具有较小 的算法>m 更好

关于java - Fast MD5 Library 是不是比 Java 7 MD5 更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14637073/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com