Java 不同压缩算法的性能比较

转载自:https://mp.weixin.qq.com/s/df1y0KbMShZveTKNBJ3aPA

本文将会对常用的几个压缩算法的性能作一下比较。进行比较的算有:

  • JDK GZIP ——这是一个压缩比高的慢速算法,压缩后的数据适合长期使用。JDK中的java.util.zip.GZIPInputStream / GZIPOutputStream便是这个算法的实现。
  • JDK deflate ——这是JDK中的又一个算法(zip文件用的就是这一算法)。它与gzip的不同之处在于,你可以指定算法的压缩级别,这样你可以在压缩时间和输出文件大小上进行平衡。可选的级别有0(不压缩),以及1(快速压缩)到9(慢速压缩)。它的实现是java.util.zip.DeflaterOutputStream / InflaterInputStream。
  • LZ4压缩算法的Java实现——这是本文介绍的算法中压缩速度最快的一个,与最快速的deflate相比,它的压缩的结果要略微差一点。
  • Snappy——这是Google开发的一个非常流行的压缩算法,它旨在提供速度与压缩比都相对较优的压缩算法。我用来测试的是这个实现。它也是遵循Apache 2.0许可证发布的。

测试文件的大小是354,509,602字节(338MB),测试结果:

输出文件的大小

实现文件大小(字节)
GZIP64,200,201
Snappy (normal)138,250,196
Snappy (framed)101,470,113
LZ4 (fast)98,316,501
LZ4 (high)82,076,909
Deflate (lvl=1)78,369,711
Deflate (lvl=2)75,261,711
Deflate (lvl=3)73,240,781
Deflate (lvl=4)68,090,059
Deflate (lvl=5)65,699,810
Deflate (lvl=6)64,200,191
Deflate (lvl=7)64,013,638
Deflate (lvl=8)63,845,758
Deflate (lvl=9)63,839,200


可以看出文件的大小相差悬殊(从60Mb到131Mb)。

压缩时间

实现压缩时间(ms)
Snappy.framedOutput2264.700
Snappy.normalOutput2201.120
Lz4.testFastNative1056.326
Lz4.testFastUnsafe1346.835
Lz4.testFastSafe1917.929
Lz4.testHighNative7489.958
Lz4.testHighUnsafe10306.973
Lz4.testHighSafe14413.622
deflate (lvl=1)4522.644
deflate (lvl=2)4726.477
deflate (lvl=3)5081.934
deflate (lvl=4)6739.450
deflate (lvl=5)7896.572
deflate (lvl=6)9783.701
deflate (lvl=7)10731.761
deflate (lvl=8)14760.361
deflate (lvl=9)14878.364
GZIP10351.887

吞吐量及效率

实现时间(ms)未压缩文件大小(Mb)吞吐量(Mb/秒)压缩后文件大小(Mb)
Snappy.normalOutput2201.12338153.5581885586131.8454742432
Snappy.framedOutput2264.7338149.247140901796.7693328857
Lz4.testFastNative1056.326338319.976976804593.7557220459
Lz4.testFastSafe1917.929338176.231758318593.7557220459
Lz4.testFastUnsafe1346.835338250.958729168893.7557220459
Lz4.testHighNative7489.95833845.127088830178.2680511475
Lz4.testHighSafe14413.62233823.450039136678.2680511475
Lz4.testHighUnsafe10306.97333832.793333212478.2680511475
deflate (lvl=1)4522.64433874.735044367974.7394561768
deflate (lvl=2)4726.47733871.512037401271.7735290527
deflate (lvl=3)5081.93433866.510112095169.8471069336
deflate (lvl=4)6739.4533850.152460512464.9452209473
deflate (lvl=5)7896.57233842.803383544262.6564025879
deflate (lvl=6)9783.70133834.547253641561.2258911133
deflate (lvl=7)10731.76133831.495296997461.0446929932
deflate (lvl=8)14760.36133822.899168929560.8825683594
deflate (lvl=9)14878.36433822.717551472760.8730316162
GZIP10351.88733832.65105192961.2258911133

  可以看到,其中大多数实现的效率是非常低的:在Xeon E5-2650处理器上,高级别的deflate大约是23Mb/秒,即使是GZIP也就只有33Mb/秒,这大概很难令人满意。同时,最快的defalte算法大概能到75Mb/秒,Snappy是150Mb/秒,而LZ4(快速,JNI实现)能达到难以置信的320Mb/秒!
  从表中可以清晰地看出目前有两种实现比较处于劣势:Snappy要慢于LZ4(快速压缩),并且压缩后的文件要更大。相反,LZ4(高压缩比)要慢于级别1到4的deflate,而输出文件的大小即便和级别1的deflate相比也要大上不少。

  因此如果需要进行“实时压缩”的话,肯定会在LZ4(快速)的JNI实现或者是级别1的deflate中进行选择。当然如果你的公司不允许使用第三方库的话你也只能使用deflate了。你还要综合考虑有多少空闲的CPU资源以及压缩后的数据要存储到哪里。比方说,如果你要将压缩后的数据存储到HDD的话,那么上述100Mb/秒的性能对你而言是毫无帮助的(假设你的文件足够大的话)——HDD的速度会成为瓶颈。同样的文件如果输出到SSD硬盘的话——即便是LZ4在它面前也显得太慢了。如果你是要先压缩数据再发送到网络上的话,最好选择LZ4,因为deflate75Mb/秒的压缩性能跟网络125Mb/秒的吞吐量相比真是小巫见大巫了。

总结
  如果你认为数据压缩非常慢的话,可以考虑下LZ4(快速)实现,它进行文本压缩能达到大约320Mb/秒的速度——这样的压缩速度对大多数应用而言应该都感知不到。
  如果你受限于无法使用第三方库或者只希望有一个稍微好一点的压缩方案的话,可以考虑下使用JDK deflate(lvl=1)进行编解码——同样的文件它的压缩速度能达到75Mb/秒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值