Java压缩算法大全&性能对比

您所在的位置:网站首页 压缩器算法 Java压缩算法大全&性能对比

Java压缩算法大全&性能对比

2023-12-29 02:33| 来源: 网络整理| 查看: 265

前言

游戏开发中,经常在玩家进入游戏的时候进行必要的信息初始化,往往这个初始化信息数据包是相对来说还是比较大的,一般在30-40kb左右,还是有必要进行压缩一下再发送消息。

不光游戏中,我们日常编程中也有其他地方可以用到,刚好前段时间看过,里面列举了一些常用的压缩算法,如下图所示:

是否可切分表示:是否可以搜索数据流的任意位置并进一步往下读取数据,这项功能在Hadoop的MapReduce中尤其适合。

下面对这几种压缩格式进行简单的介绍,并进行压力测试,进行性能比较

DEFLATE压缩格式

DEFLATE是同时使用了LZ77算法与哈夫曼编码(Huffman Coding)的一个无损数据压缩算法。

DEFLATE压缩与解压的源代码可以在自由、通用的压缩库zlib上找到,zlib官网:www.zlib.net/

jdk中对zlib压缩库提供了支持,压缩类Deflater和解压类Inflater,Deflater和Inflater都提供了native方法

private native int deflateBytes(long addr,                                  byte[] b,                                  int off,                                  int len,                                 int flush); private native int inflateBytes(long addr,                                  byte[] b,                                  int off,                                  int len)                   throws DataFormatException;

所有可以直接使用jdk提供的压缩类Deflater和解压类Inflater

实现代码如下: public static byte[] compress(byte input[]) {     ByteArrayOutputStream bos = new ByteArrayOutputStream();     Deflater compressor = new Deflater(1);     try {         compressor.setInput(input);         compressor.finish();         final byte[] buf = new byte[2048];         while (!compressor.finished()) {             int count = compressor.deflate(buf);             bos.write(buf, 0, count);         }     } finally {         compressor.end();     }     return bos.toByteArray(); } public static byte[] uncompress(byte[] input) throws DataFormatException {     ByteArrayOutputStream bos = new ByteArrayOutputStream();     Inflater decompressor = new Inflater();     try {         decompressor.setInput(input);         final byte[] buf = new byte[2048];         while (!decompressor.finished()) {             int count = decompressor.inflate(buf);             bos.write(buf, 0, count);         }     } finally {         decompressor.end();     }     return bos.toByteArray(); }

可以指定算法的压缩级别,这样你可以在压缩时间和输出文件大小上进行平衡。

可选的级别有:0(不压缩),以及1(快速压缩)到9(慢速压缩)。

这里使用的是以速度为优先。

gzip压缩格式

gzip的实现算法还是deflate,只是在deflate格式上增加了文件头和文件尾。

同样jdk也对gzip提供了支持,分别是GZIPOutputStream 和 GZIPInputStream类。

同样可以发现GZIPOutputStream是继承于DeflaterOutputStream的,GZIPInputStream继承于InflaterInputStream,并且可以在源码中发现writeHeader和writeTrailer方法:

private void writeHeader() throws IOException {      ...... } private void writeTrailer(byte[] buf, int offset) throws IOException {      ...... } 具体的代码实现如下: public static byte[] compress(byte srcBytes[]) {     ByteArrayOutputStream out = new ByteArrayOutputStream();     GZIPOutputStream gzip;     try {         gzip = new GZIPOutputStream(out);         gzip.write(srcBytes);         gzip.close();     } catch (IOException e) {         e.printStackTrace();     }     return out.toByteArray(); } public static byte[] uncompress(byte[] bytes) {     ByteArrayOutputStream out = new ByteArrayOutputStream();     ByteArrayInputStream in = new ByteArrayInputStream(bytes);     try {         GZIPInputStream ungzip = new GZIPInputStream(in);         byte[] buffer = new byte[2048];         int n;         while ((n = ungzip.read(buffer)) >= 0) {             out.write(buffer, 0, n);         }     } catch (IOException e) {         e.printStackTrace();     }     return out.toByteArray(); } bzip2压缩格式

bzip2是Julian Seward开发并按照自由软件/开源软件协议发布的数据压缩算法及程序。

Seward在1996年7月第一次公开发布了bzip2 0.15版,在随后几年中这个压缩工具稳定性得到改善并且日渐流行,Seward在2000年晚些时候发布了1.0版。

bzip2比传统的gzip的压缩效率更高,但是它的压缩速度较慢。

jdk中没有对bzip2实现,但是在commons-compress中进行了实现,maven引入:

    org.apache.commons     commons-compress     1.12 具体的代码实现如下: public static byte[] compress(byte srcBytes[]) throws IOException {     ByteArrayOutputStream out = new ByteArrayOutputStream();     BZip2CompressorOutputStream bcos = new BZip2CompressorOutputStream(out);     bcos.write(srcBytes);     bcos.close();     return out.toByteArray(); } public static byte[] uncompress(byte[] bytes) {     ByteArrayOutputStream out = new ByteArrayOutputStream();     ByteArrayInputStream in = new ByteArrayInputStream(bytes);     try {         BZip2CompressorInputStream ungzip = new BZip2CompressorInputStream(                 in);         byte[] buffer = new byte[2048];         int n;         while ((n = ungzip.read(buffer)) >= 0) {             out.write(buffer, 0, n);         }     } catch (IOException e) {         e.printStackTrace();     }     return out.toByteArray(); }

下面的介绍的lzo,lz4以及snappy这3中压缩算法,均已压缩速度为优先,但压缩效率稍逊一筹。

lzo压缩格式

LZO是致力于解压速度的一种数据压缩算法,LZO是Lempel-Ziv-Oberhumer的缩写。这个算法是无损算法。

需要引入第三方库,maven引入:

    org.anarres.lzo     lzo-core     1.0.5 具体实现代码: public static byte[] compress(byte srcBytes[]) throws IOException {     LzoCompressor compressor = LzoLibrary.getInstance().newCompressor(             LzoAlgorithm.LZO1X, null);     ByteArrayOutputStream os = new ByteArrayOutputStream();     LzoOutputStream cs = new LzoOutputStream(os, compressor);     cs.write(srcBytes);     cs.close();     return os.toByteArray(); } public static byte[] uncompress(byte[] bytes) throws IOException {     LzoDecompressor decompressor = LzoLibrary.getInstance()             .newDecompressor(LzoAlgorithm.LZO1X, null);     ByteArrayOutputStream baos = new ByteArrayOutputStream();     ByteArrayInputStream is = new ByteArrayInputStream(bytes);     LzoInputStream us = new LzoInputStream(is, decompressor);     int count;     byte[] buffer = new byte[2048];     while ((count = us.read(buffer)) != -1) {         baos.write(buffer, 0, count);     }     return baos.toByteArray(); } lz4压缩格式

LZ4是一种无损数据压缩算法,着重于压缩和解压缩速度更多wikilz4

maven引入第三方库:

    net.jpountz.lz4     lz4     1.2.0 具体代码实现: public static byte[] compress(byte srcBytes[]) throws IOException {     LZ4Factory factory = LZ4Factory.fastestInstance();     ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();     LZ4Compressor compressor = factory.fastCompressor();     LZ4BlockOutputStream compressedOutput = new LZ4BlockOutputStream(             byteOutput, 2048, compressor);     compressedOutput.write(srcBytes);     compressedOutput.close();     return byteOutput.toByteArray(); } public static byte[] uncompress(byte[] bytes) throws IOException {     LZ4Factory factory = LZ4Factory.fastestInstance();     ByteArrayOutputStream baos = new ByteArrayOutputStream();     LZ4FastDecompressor decompresser = factory.fastDecompressor();     LZ4BlockInputStream lzis = new LZ4BlockInputStream(             new ByteArrayInputStream(bytes), decompresser);     int count;     byte[] buffer = new byte[2048];     while ((count = lzis.read(buffer)) != -1) {         baos.write(buffer, 0, count);     }     lzis.close();     return baos.toByteArray(); } snappy压缩格式

Snappy(以前称Zippy)是Google基于LZ77的思路用C++语言编写的快速数据压缩与解压程序库,并在2011年开源。

它的目标并非最大压缩率或与其他压缩程序库的兼容性,而是非常高的速度和合理的压缩率。

maven引入第三方库:

    org.xerial.snappy     snappy-java     1.1.2.6 具体代码实现: public static byte[] compress(byte srcBytes[]) throws IOException {     return  Snappy.compress(srcBytes); } public static byte[] uncompress(byte[] bytes) throws IOException {     return Snappy.uncompress(bytes); } 压力测试

以下对35kb玩家数据进行压缩和解压测试,相对来说35kb数据还是很小量的数据。

所有以下测试结果只是针对指定的数据量区间进行测试的结果,并不能说明哪种压缩算法好与不好。

对35kb数据进行2000次压缩和解压缩测试,测试代码如下:

public static void main(String[] args) throws Exception {     FileInputStream fis = new FileInputStream(new File("player.dat"));     FileChannel channel = fis.getChannel();     ByteBuffer bb = ByteBuffer.allocate((int) channel.size());     channel.read(bb);     byte[] beforeBytes = bb.array();     int times = 2000;     System.out.println("压缩前大小:" + beforeBytes.length + " bytes");     long startTime1 = System.currentTimeMillis();     byte[] afterBytes = null;     for (int i = 0; i 


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3