脚本宝典收集整理的这篇文章主要介绍了

java.util.zip.CRC32和java.util.zip.Adler32的性能对比分析

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。

原文:java.util.zip.CRC32 and java.util.zip.Adler32 performance
作者:Mikhail Vorontsov

校验码是把任意长度的字节内容输入通过特定算法变换为一个长度较短的字节数组(在CRC32和Adler32中变换为整数(Integer))。校验码最主要的一个特点是,即使输入内容发生了很小的变化,输出内容也会有极为明显的差别。校验算法通常在以下两种场景中使用:

  • 当主机已经分别接收到一个完整文件和其对应的校验码时,我们要计算出整个文件的校验码,与接收到的校验码进行对比,来确认文件在传输的过程中没有被篡改。
  • 当主机正在从某个输入流源源不断地读取文件时,校验码的计算是实时的,每次校验操作都只对文件的一部分进行处理。当某些原因导致主机与输入设备的连接断开,主机尝试重新传输时,我们会使用最后一次计算得到的校验码和读取到的文件位置与当前重传的数据内容进行比较,以免对前面已经传输过的数据进行重新处理,从而使得传输可以从当前位置继续进行。

在标准JDK中,最常使用的校验算法是java.util.zip.CRC32。许多开发者认为这是Java唯一的标准校验算法实现(其中也有人会说这是标准的CRC(Cyclic Redundancy Check,循环冗余校验)实现)。实际上,Java中还有另一种校验算法叫java.util.zip.Adler32,这两种算法都实现了同一个接口:java.util.zip.Checksum。

这两种校验算法是有区别的,Adler32比CRC32稍微弱一些,不过如果当需要校验的内容长达几千字节甚至更多时,你可以忽略校验质量上的差异。更重要的是,Adler32的计算速度比CRC32快。下面的列表对这两种校验算法的处理速度进行了比较,处理的内容是一个500MB的存档文件(文件已经预先读取到内存中)

500MB数据容校验速度对比

Adler32,一次性处理 CRC32,一次性处理 Adler32,每次处理区块大小10 bytes CRC32,每次处理区块大小10 bytes Adler32,每次处理区块大小1000 bytes CRC32,每次处理区块大小1000 bytes
Java 6 0.233 s 1.526 s 3.585 s 4.119 s 0.253 s 1.545 s
Java 7 0.227 s 0.666 s 3.684 s 3.691 s 0.267 s 0.699 s

如你所见,在Java 6中,当单次处理的区块足够大时,Adler32的速度是CRC32的5~6倍;而在Java 7中明确地对CRC32进行了性能优化,Adler32的速度只比CRC32快了2~3倍。使用小容量的区块进行处理时,JNI调用的成本是影响速度的最大因素。

有人可能觉得0.3s和1.5s的时间差异对于500MB的内容来说没有什么值得关注的地方,这并不完全正确。如今硬盘的读取速度能达到100M/s,读取500MB数据最多只需要5s,在这样的情况下,额外的1秒时间(1.5-0.3 s)就会造成20%的性能下降。换个方式说,你可以理解为“我们的系统使用CRC32能达到500,000条信息/每秒的处理速度,而使用Adler32可以达到600,000条信息/每秒”。

总结

如果你可以自由选择校验算法实现,你可以先尝试使用Adler32。如果它的校验质量对你来说已经足够了的话,使用它比CRC32要更好。无论在什么情况下,你应当使用Checksum接口来访问Adler32/CRC32的逻辑。

在计算校验码时,请至少使用500 bytes的分区大小,否则JNI调用会造成不可忽略的时间消耗。

总结

以上是脚本宝典为你收集整理的

java.util.zip.CRC32和java.util.zip.Adler32的性能对比分析

全部内容,希望文章能够帮你解决

java.util.zip.CRC32和java.util.zip.Adler32的性能对比分析

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过