java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java数据压缩所有方式性能测试

Java如何实现数据压缩所有方式性能测试

作者:赵广陆

本文介绍了多种压缩算法及其在Java中的实现,包括LZ4、BZip2、Deflate、Gzip和7z等,LZ4以其高效的压缩和解压缩速度而受到青睐,特别是在大数据处理场景中,通过对比不同压缩算法的性能和压缩率,我们选择了最适合当前项目需求的压缩工具

1 BZip方式

ZIP文件格式是一种数据压缩和文档储存的文件格式,原名Deflate,发明者为菲尔·卡茨(Phil Katz),他于1989年1月公布了该格式的资料。ZIP通常使用后缀名“.zip”,它的MIME格式为application/zip。当前,ZIP格式属于几种主流的压缩格式之一,其竞争者包括RAR格式以及开放源码的7z格式。从性能上比较,RAR及7z格式较ZIP格式压缩率较高,而7-Zip由于提供了免费的压缩工具而逐渐在更多的领域得到应用。

Microsoft从Windows ME操作系统开始内置对zip格式的支持,即使用户的计算机上没有安装解压缩软件,也能打开和制作zip格式的压缩文件,OS X和流行的Linux操作系统也对zip格式提供了类似的支持。因此如果在网络上传播和分发文件,zip格式往往是最常用的选择。

1.1 引入依赖

        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.10.6</version>
        </dependency>

1.2 BZip工具类代码

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.tools.bzip2.CBZip2InputStream;
import org.apache.tools.bzip2.CBZip2OutputStream;

public class BZip2Util {

    private static final int BUFFER_SIZE = 8192;

    public static byte[] compress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (CBZip2OutputStream bzip2 = new CBZip2OutputStream(bos)) {
            bzip2.write(bytes);
            bzip2.finish();
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("BZip2 compress error", e);
        }
    }

    public static byte[] decompress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        try (CBZip2InputStream bzip2 = new CBZip2InputStream(bis)) {
            byte[] buffer = new byte[BUFFER_SIZE];
            int n;
            while ((n = bzip2.read(buffer)) > -1) {
                out.write(buffer, 0, n);
            }
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("BZip2 decompress error", e);
        }
    }
}

1.3 BZip2工具类代码

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.tools.bzip2.CBZip2InputStream;
import org.apache.tools.bzip2.CBZip2OutputStream;

public class BZip2Util {

    private static final int BUFFER_SIZE = 8192;

    public static byte[] compress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (CBZip2OutputStream bzip2 = new CBZip2OutputStream(bos)) {
            bzip2.write(bytes);
            bzip2.finish();
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("BZip2 compress error", e);
        }
    }

    public static byte[] decompress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        try (CBZip2InputStream bzip2 = new CBZip2InputStream(bis)) {
            byte[] buffer = new byte[BUFFER_SIZE];
            int n;
            while ((n = bzip2.read(buffer)) > -1) {
                out.write(buffer, 0, n);
            }
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("BZip2 decompress error", e);
        }
    }
}

2 Deflater方式

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

public class DeflaterUtil {

    private DeflaterUtil() {

    }

    private static final int BUFFER_SIZE = 8192;

    public static byte[] compress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        int lenght = 0;
        Deflater deflater = new Deflater();
        deflater.setInput(bytes);
        deflater.finish();
        byte[] outputBytes = new byte[BUFFER_SIZE];
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            while (!deflater.finished()) {
                lenght = deflater.deflate(outputBytes);
                bos.write(outputBytes, 0, lenght);
            }
            deflater.end();
            return bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("Deflater compress error", e);
        }
    }

    public static byte[] decompress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        int length = 0;
        Inflater inflater = new Inflater();
        inflater.setInput(bytes);
        byte[] outputBytes = new byte[BUFFER_SIZE];
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();) {
            while (!inflater.finished()) {
                length = inflater.inflate(outputBytes);
                if (length == 0) {
                    break;
                }
                bos.write(outputBytes, 0, length);
            }
            inflater.end();
            return bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException("Deflater decompress error", e);
        }
    }

}

3 Gzip方式

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipUtil {

    private GzipUtil() {

    }

    private static final int BUFFER_SIZE = 8192;

    public static byte[] compress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (GZIPOutputStream gzip = new GZIPOutputStream(out)) {
            gzip.write(bytes);
            gzip.flush();
            gzip.finish();
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("gzip compress error", e);
        }
    }

    public static byte[] decompress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (GZIPInputStream gunzip = new GZIPInputStream(new ByteArrayInputStream(bytes))) {
            byte[] buffer = new byte[BUFFER_SIZE];
            int n;
            while ((n = gunzip.read(buffer)) > -1) {
                out.write(buffer, 0, n);
            }
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("gzip decompress error", e);
        }
    }
}

4 Lz4方式

4.1 简介

Lz4压缩算法是由Yann Collet在2011年设计实现的,lz4属于lz77系列的压缩算法。lz77严格意义上来说不是一种算法,而是一种编码理论,它只定义了原理,并没有定义如何实现。基于lz77理论衍生的算法除lz4以外,还有lzss、lzb、lzh等。

lz4是目前基于综合来看效率最高的压缩算法,更加侧重于压缩解压缩速度,压缩比并不突出,本质上就是时间换空间。

对于github上给出的lz4性能介绍:每核压缩速度大于500MB/s,多核CPU可叠加;它所提供的解码器也是极其快速的,每核可达GB/s量级。

4.2 算法思想

4.3 算法实现

4.3.1 lz4数据格式

压缩块有多个序列组成,一个序列是由一组字面量(非压缩字节),后跟一个匹配副本。每个序列以token开始,字面量和匹配副本的长度是有token以及offset决定的。

下图为单个序列的数据格式,一个完整的lz4压缩块是由多个序列组成的。

2、lz4压缩过程

lz4遵循上面说到的lz77思想理论,通过滑动窗口、hash表、数据编码等操作实现数据压缩。压缩过程以至少4字节为扫描窗口查找匹配,每次移动1字节进行扫描,遇到重复的就进行压缩。

举个例子:给出一个字符串: abcde_fghabcde_ghxxahcde,描述出此字符串的压缩过程

ps:我们按照6字节扫描窗口,每次1字节来进行扫描

最终,这样压缩过程就结束了,得到这样一个字节串[-110, 97, 98, 99, 100, 101, 95, 102, 103, 104, 9, 0, -112, 103, 104, 120, 120, 97, 104, 99, 100, 101]。大家可能在看到这段内容可能有些懵逼,我在解压过程解释一下。

3、lz4解压过程

下图是对上面压缩串的解释:

这里简单记录下解压的过程:

4.4 Lz4-Java

lz4/lz4-java是由Rei Odaira等人写的一套使用lz4压缩的Java类库。

4.4.1 简介

该类库提供了对两种压缩方法的访问,他们都能生成有效的lz4流:

快速扫描(lz4)

高压缩(lz4hc)

这两种压缩算法产生的流使用相同的压缩格式,解压缩速度非常快,可以由相同的解压缩实例解压缩

4.4.2 类库

该类库提供了几个关键类,这里简单介绍一下

Lz4 API的入口点,该类有3个实例

只有safe Java实例才能保证在JVM上工作,因此建议使用fastestInstance()或fastestJavaInstance()来拉取LZ4Factory实例。

压缩器有两种,一种是fastCompressor,也就是lz4简介中说的快速扫描压缩器;另一种是highCompressor,是实现高压缩率压缩器(lz4hc)。

lz4-java提供了两个解压器:LZ4FastDecompressor;LZ4SafeDecompressor

两者不同点在于:LZ4FastDecompressor在解压缩时是已知源字符串长度,而LZ4SafeDecompressor在解压缩时是已知压缩字段的长度

使用:

上面说到的两个压缩器和两个解压缩器,在压缩和解压缩的时候,是可以互换的,比如说FastCompressor可以和LZ4SafeDecompressor搭配使用这样,因为两种压缩算法生成的流格式是一样的,无论用哪个解压缩器都能解压。

在说完上面基本的类之后,再来看下lz4-Java类库给我们提供流式传输类:LZ4BlockOutputStream(输出流-编码)、LZ4BlockInputStream(输入流-解码)

下面这段代码是使用示例:

package com.oldlu.compress.utils;

import net.jpountz.lz4.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

public class Lz4Utils {
    private static final int ARRAY_SIZE = 4096;
    private static LZ4Factory factory = LZ4Factory.fastestInstance();
    private static LZ4Compressor compressor = factory.fastCompressor();
    private static LZ4FastDecompressor decompressor = factory.fastDecompressor();
    private static LZ4SafeDecompressor safeDecompressor = factory.safeDecompressor();

    public static byte[] compress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            LZ4BlockOutputStream lz4BlockOutputStream = new LZ4BlockOutputStream(outputStream, ARRAY_SIZE, compressor);
            lz4BlockOutputStream.write(bytes);
            lz4BlockOutputStream.finish();
            return outputStream.toByteArray();
        } catch (Exception e) {
            System.err.println("Lz4压缩失败");
        }
        return null;
    }

    public static byte[] uncompress(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream(ARRAY_SIZE);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
            LZ4BlockInputStream decompressedInputStream = new LZ4BlockInputStream(inputStream, decompressor);
            int count;
            byte[] buffer = new byte[ARRAY_SIZE];
            while ((count = decompressedInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, count);
            }
            return outputStream.toByteArray();
        } catch (Exception e) {
            System.err.println("lz4解压缩失败");
        }
        return null;
    }

    public static void main(String[] args) {
        byte[] bytes = "abcde_fghabcde_ghxxahcde".getBytes(StandardCharsets.UTF_8);

        byte[] compress = compress(bytes);

        byte[] decompress = uncompress(compress);
    }
}

5 SevenZ方式

5.1 引入依赖

        <dependency>
            <groupId>org.tukaani</groupId>
            <artifactId>xz</artifactId>
            <version>1.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.19</version>
        </dependency>

5.2 工具类代码

import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class SevenZUtil {

    private static final int BUFFER_SIZE = 8192;

    public static byte[] compress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel();
        try (SevenZOutputFile z7z = new SevenZOutputFile(channel)) {
            SevenZArchiveEntry entry = new SevenZArchiveEntry();
            entry.setName("sevenZip");
            entry.setSize(bytes.length);
            z7z.putArchiveEntry(entry);
            z7z.write(bytes);
            z7z.closeArchiveEntry();
            z7z.finish();
            return channel.array();
        } catch (IOException e) {
            throw new RuntimeException("SevenZ compress error", e);
        }
    }

    public static byte[] decompress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel(bytes);
        try (SevenZFile sevenZFile = new SevenZFile(channel)) {
            byte[] buffer = new byte[BUFFER_SIZE];
            while (sevenZFile.getNextEntry() != null) {
                int n;
                while ((n = sevenZFile.read(buffer)) > -1) {
                    out.write(buffer, 0, n);
                }
            }
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("SevenZ decompress error", e);
        }
    }

 
}

6 Zip方式

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


public class ZipUtil {

    private static final int BUFFER_SIZE = 8192;

    public static byte[] compress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (ZipOutputStream zip = new ZipOutputStream(out)) {
            ZipEntry entry = new ZipEntry("zip");
            entry.setSize(bytes.length);
            zip.putNextEntry(entry);
            zip.write(bytes);
            zip.closeEntry();
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("Zip compress error", e);
        }
    }

    public static byte[] decompress(byte[] bytes) {
        if (bytes == null) {
            throw new NullPointerException("bytes is null");
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try (ZipInputStream zip = new ZipInputStream(new ByteArrayInputStream(bytes))) {
            byte[] buffer = new byte[BUFFER_SIZE];
            while (zip.getNextEntry() != null) {
                int n;
                while ((n = zip.read(buffer)) > -1) {
                    out.write(buffer, 0, n);
                }
            }
            return out.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("Zip decompress error", e);
        }
    }
}

7 性能对比

我们可以使用它来和其他压缩类进行一个性能对比

测试源代码:

package com.oldlu.compress.test;

import com.oldlu.compress.domain.User;
import com.oldlu.compress.service.UserService;
import com.oldlu.compress.utils.*;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;



@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class PerformanceTest {
    /**
     * 用来序列化的用户对象
     */
    @State(Scope.Benchmark)
    public static class CommonState {
        User user;
        byte[] originBytes;
        byte[] lz4CompressBytes;
        byte[] snappyCompressBytes;
        byte[] gzipCompressBytes;
        byte[] bzipCompressBytes;
        byte[] deflateCompressBytes;

        @Setup(Level.Trial)
        public void prepare() {
            UserService userService = new UserService();
            user = userService.get();
            originBytes = ProtostuffUtils.serialize(user);
            lz4CompressBytes = Lz4Utils.compress(originBytes);
            snappyCompressBytes = SnappyUtils.compress(originBytes);
            gzipCompressBytes = GzipUtils.compress(originBytes);
            bzipCompressBytes = Bzip2Utils.compress(originBytes);
            deflateCompressBytes = DeflateUtils.compress(originBytes);
        }
    }

    /**
     * Lz4压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] lz4Compress(CommonState commonState) {
        return Lz4Utils.compress(commonState.originBytes);
    }

    /**
     * lz4解压缩
     *
     * @param commonState
     */
    @Benchmark
    public byte[] lz4Uncompress(CommonState commonState) {
        return Lz4Utils.uncompress(commonState.lz4CompressBytes);
    }

    /**
     * snappy压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] snappyCompress(CommonState commonState) {
        return SnappyUtils.compress(commonState.originBytes);
    }


    /**
     * snappy解压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] snappyUncompress(CommonState commonState) {
        return SnappyUtils.uncompress(commonState.snappyCompressBytes);
    }


    /**
     * Gzip压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] gzipCompress(CommonState commonState) {
        return GzipUtils.compress(commonState.originBytes);
    }

    /**
     * Gzip解压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] gzipUncompress(CommonState commonState) {
        return GzipUtils.uncompress(commonState.gzipCompressBytes);
    }

    /**
     * bzip2压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] bzip2Compress(CommonState commonState) {
        return Bzip2Utils.compress(commonState.originBytes);
    }

    /**
     * bzip2压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] bzip2Uncompress(CommonState commonState) {
        return Bzip2Utils.uncompress(commonState.bzipCompressBytes);
    }

    /**
     * bzip2压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] deflateCompress(CommonState commonState) {
        return DeflateUtils.compress(commonState.originBytes);
    }

    /**
     * bzip2压缩
     *
     * @param commonState
     * @return
     */
    @Benchmark
    public byte[] deflateUncompress(CommonState commonState) {
        return DeflateUtils.uncompress(commonState.deflateCompressBytes);
    }


    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(PerformanceTest.class.getSimpleName())
                .forks(1)
                .threads(1)
                .warmupIterations(10)
                .measurementIterations(10)
                .result("PerformanceTest.json")
                .resultFormat(ResultFormatType.JSON).build();
        new Runner(opt).run();
    }
}

性能测试图:

附上lz4官网给出的性能测试图和自己测试的性能图,有些差异,有可能对于压缩数据的不同导致的差异。

在公司对于特征内容的压缩,观察lz4和snappy的对比,看上去lz4和snappy的压缩和解压缩的性能差不多,但lz4更稳定些,尖刺场景少。由于设计公司内部内容,就不粘图了。

7.1 压缩率对比

在压缩率上,按照从高到低是:bzip2 > Deflate > Gzip > lz4 > snappy

package com.oldlu.compress.demo;

import com.alibaba.fastjson.JSONObject;
import com.oldlu.compress.domain.User;
import com.oldlu.compress.service.UserService;
import com.oldlu.compress.utils.*;

import java.nio.charset.StandardCharsets;


public class CompressDemo {
    public static void main(String[] args) {
        User user = new UserService().get();
        // json序列化
        byte[] origin_json = JSONObject.toJSONBytes(user);
        System.out.println("原始json字节数: " + origin_json.length);
        // pb序列化
        byte[] origin = ProtostuffUtils.serialize(user);
        System.out.println("原始pb字节数: " + origin.length);

        testGzip(origin, user);
        testSnappy(origin, user);
        testLz4(origin, user);
        testBzip2(origin, user);
        testDeflate(origin, user);

    }

    private static void test(){
        System.out.println("--------------------");
        String str = getString();
        byte[] source = str.getBytes(StandardCharsets.UTF_8);
        byte[] compress = Lz4Utils.compress(source);
        // 将compress转为字符串
        System.out.println(translateString(compress));
        System.out.println();
        System.out.println("--------------------");
        String str2 = getString2();
        byte[] source2 = str2.getBytes(StandardCharsets.UTF_8);
        byte[] compress2 = Lz4Utils.compress(source2);
        byte[] uncompress = Lz4Utils.uncompress(compress2);
        System.out.println();
    }

    private static String translateString(byte[] bytes) {
        char[] chars = new char[bytes.length];
        for (int i = 0; i < chars.length; i++) {
            chars[i] = (char) bytes[i];
        }
        String str = new String(chars);
        return str;
    }

    private static String getString() {
        return "fghabcde_bcdefgh_abcdefghxxxxxxx";
    }

    private static String getString2() {
        return "abcde_fghabcde_ghxxahcde";
    }


    private static void testGzip(byte[] origin, User user) {
        System.out.println("---------------GZIP压缩---------------");
        // Gzip压缩
        byte[] gzipCompress = GzipUtils.compress(origin);
        System.out.println("Gzip压缩: " + gzipCompress.length);
        byte[] gzipUncompress = GzipUtils.uncompress(gzipCompress);
        System.out.println("Gzip解压缩: " + gzipUncompress.length);
        User deUser = ProtostuffUtils.deserialize(gzipUncompress, User.class);
        System.out.println("对象是否相等: " + user.equals(deUser));
    }

    private static void testSnappy(byte[] origin, User user) {
        System.out.println("---------------Snappy压缩---------------");
        // Snappy压缩
        byte[] snappyCompress = SnappyUtils.compress(origin);
        System.out.println("Snappy压缩: " + snappyCompress.length);
        byte[] snappyUncompress = SnappyUtils.uncompress(snappyCompress);
        System.out.println("Snappy解压缩: " + snappyUncompress.length);
        User deUser = ProtostuffUtils.deserialize(snappyUncompress, User.class);
        System.out.println("对象是否相等: " + user.equals(deUser));
    }

    private static void testLz4(byte[] origin, User user) {
        System.out.println("---------------Lz4压缩---------------");
        // Lz4压缩
        byte[] Lz4Compress = Lz4Utils.compress(origin);
        System.out.println("Lz4压缩: " + Lz4Compress.length);
        byte[] Lz4Uncompress = Lz4Utils.uncompress(Lz4Compress);
        System.out.println("Lz4解压缩: " + Lz4Uncompress.length);
        User deUser = ProtostuffUtils.deserialize(Lz4Uncompress, User.class);
        System.out.println("对象是否相等: " + user.equals(deUser));
    }

    private static void testBzip2(byte[] origin, User user) {
        System.out.println("---------------bzip2压缩---------------");
        // bzip2压缩
        byte[] bzip2Compress = Bzip2Utils.compress(origin);
        System.out.println("bzip2压缩: " + bzip2Compress.length);
        byte[] bzip2Uncompress = Bzip2Utils.uncompress(bzip2Compress);
        System.out.println("bzip2解压缩: " + bzip2Uncompress.length);
        User deUser = ProtostuffUtils.deserialize(bzip2Uncompress, User.class);
        System.out.println("对象是否相等: " + user.equals(deUser));
    }

    private static void testDeflate(byte[] origin, User user) {
        System.out.println("---------------Deflate压缩---------------");
        // Deflate压缩
        byte[] deflateCompress = DeflateUtils.compress(origin);
        System.out.println("Deflate压缩: " + deflateCompress.length);
        byte[] deflateUncompress = DeflateUtils.uncompress(deflateCompress);
        System.out.println("Deflate解压缩: " + deflateUncompress.length);
        User deUser = ProtostuffUtils.deserialize(deflateUncompress, User.class);
        System.out.println("对象是否相等: " + user.equals(deUser));
    }
}
原始json字节数: 5351
原始pb字节数: 3850
---------------GZIP压缩---------------
Gzip压缩: 2170
Gzip解压缩: 3850
对象是否相等: true
---------------Snappy压缩---------------
Snappy压缩: 3396
Snappy解压缩: 3850
对象是否相等: true
---------------Lz4压缩---------------
Lz4压缩: 3358
Lz4解压缩: 3850
对象是否相等: true
---------------bzip2压缩---------------
bzip2压缩: 2119
bzip2解压缩: 3850
对象是否相等: true
---------------Deflate压缩---------------
Deflate压缩: 2167
Deflate解压缩: 3850
对象是否相等: true

Process finished with exit code 0

8 总结

通过上面几节的学习,对lz4有了大致的了解,它的压缩和解压缩效率是非常好的,压缩比相较于其他压缩工具来讲并不是很突出,其压缩比取决于压缩内容的重复率。

在压缩场景中,选择合适的压缩工具,各种压缩工具均有其利弊,扬其长、避其短,才能使得我们的工作更有效。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文