Java 序列化反序列化对比

栏目: Java · 发布时间: 5年前

内容简介:Java 序列化工具对比,对比以下序列化工具对数据的存储大小以及计算耗时:对 100000 个 User 进行序列化以及反序列化操作,输出操作时间以及各个工具序列化后累计的数据的长度:耗时:JDK > Hessian > Protostuff > Kryo

Java 序列化 工具 对比,对比以下序列化工具对数据的存储大小以及计算耗时:

  • JDK 1.8
  • Hessian 4.0.60
  • Kryo 4.0.2
  • Protostuff:1.6.0

版本依赖

<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>4.0.2</version>
</dependency>

<dependency>
    <groupId>com.caucho</groupId>
    <artifactId>hessian</artifactId>
    <version>4.0.60</version>
</dependency>

<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>1.6.0</version>
</dependency>

<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>1.6.0</version>
</dependency>

测试代码

对 100000 个 User 进行序列化以及反序列化操作,输出操作时间以及各个工具序列化后累计的数据的长度:

/**
 * 序列化器对比
 * Created by Captain on 06/03/2019.
 */
public class SerializerUtil {

    private static Kryo kryo = new Kryo();

    /**
     * JDK 序列化
     */
    public static byte[] serializable(Object obj) {
        if (obj == null) {
            return null;
        }
        if ( obj instanceof String ) {
            return ((String) obj).getBytes();
        }
        ObjectOutputStream oos = null;
        ByteArrayOutputStream baos = null;
        try {
            // 序列化
            baos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(baos);
            oos.writeObject(obj);
            byte[] bytes = baos.toByteArray();
            return bytes;
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * JDK 反序列化
     */
    public static Object unserializable(byte[] bytes){
        ByteArrayInputStream bais = null;
        try {
            // 反序列化
            bais = new ByteArrayInputStream(bytes);
            ObjectInputStream ois = new ObjectInputStream(bais);
            return ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * kryo 反序列化
     */
    public static Object unserializableKryo(byte[] bytes){
        if (bytes == null) {
            return null;
        }
        try {
            // 反序列化
            Input input = new Input(new ByteArrayInputStream(bytes));
            Object obj = kryo.readClassAndObject(input);
            input.close();
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * kryo 序列化
     */
    public static byte[] serializableKryo(Object obj){
        if (obj == null) {
            return null;
        }
        if ( obj instanceof String ) {
            return ((String) obj).getBytes();
        }
        try {
            // 序列化
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Output output = new Output(baos);
            kryo.writeClassAndObject(output, obj);
            output.flush();
            output.close();
            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * hessian 序列化
     */
    public static byte[] serializableHessian(Object obj){
        ByteArrayOutputStream byteArrayOutputStream = null;
        HessianOutput hessianOutput = null;
        try {
            byteArrayOutputStream = new ByteArrayOutputStream();
            hessianOutput = new HessianOutput(byteArrayOutputStream);
            hessianOutput.writeObject(obj);
            return byteArrayOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                byteArrayOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                hessianOutput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * hessian 反序列化
     */
    public static Object unserializableHessian(byte[] bytes){
        ByteArrayInputStream byteArrayInputStream = null;
        HessianInput hessianInput = null;
        try {
            byteArrayInputStream = new ByteArrayInputStream(bytes);
            // Hessian的反序列化读取对象
            hessianInput = new HessianInput(byteArrayInputStream);
            return hessianInput.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                byteArrayInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                hessianInput.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * protostuff 序列化
     */
    public static <T> byte[] serializableProtostuff(T obj){
        try {
            RuntimeSchema schema = RuntimeSchema.createFrom(obj.getClass());
            return ProtostuffIOUtil.toByteArray(obj, schema, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
        } catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * protostuff 反序列化
     */
    public static Object unserializableProtostuff(byte[] bytes, Class clazz){
        RuntimeSchema schema = RuntimeSchema.createFrom(clazz);
        Object obj = schema.newMessage();
        ProtostuffIOUtil.mergeFrom(bytes, obj, schema);
        return obj;
    }

    public static void main(String[] args) {

        final int OBJECT_COUNT = 100000;
        User user = new User();
        
        long sum = 0;
        long start = System.currentTimeMillis();
        for ( int i = 0 ; i <= OBJECT_COUNT ; i++ ){
            user.setId(i);
            user.setName("Captain" + i);
            user.setAge(18 + i);
            byte[] bytes = serializable(user);
            sum += bytes.length;
            unserializable(bytes);
        }
        System.out.println("JDK 1.8 序列化反序列化 -> 耗时 : " + (System.currentTimeMillis() - start) + " , 长度 : " + sum);

        long sum2 = 0;
        long start2 = System.currentTimeMillis();
        for ( int i = 0 ; i <= OBJECT_COUNT ; i++ ){
            user.setId(i);
            user.setName("Captain" + i);
            user.setAge(18 + i);
            byte[] bytes = serializableKryo(user);
            sum2 += bytes.length;
            unserializableKryo(bytes);
        }
        System.out.println("Kryo 4.0.2 序列化反序列化 -> 耗时 : " + (System.currentTimeMillis() - start2) + " , 长度 : " + sum2);

        long sum3 = 0;
        long start3 = System.currentTimeMillis();
        for ( int i = 0 ; i <= OBJECT_COUNT ; i++ ){
            user.setId(i);
            user.setName("Captain" + i);
            user.setAge(18 + i);
            byte[] bytes = serializableHessian(user);
            sum3 += bytes.length;
            unserializableHessian(bytes);
        }
        System.out.println("Hessian 4.0.60 序列化反序列化 -> 耗时 : " + (System.currentTimeMillis() - start3) + " , 长度 : " + sum3);

        long sum4 = 0;
        long start4 = System.currentTimeMillis();
        for ( int i = 0 ; i <= OBJECT_COUNT ; i++ ){
            user.setId(i);
            user.setName("Captain" + i);
            user.setAge(18 + i);
            byte[] bytes = serializableProtostuff(user);
            sum4 += bytes.length;
            unserializableProtostuff(bytes, User.class);
        }
        System.out.println("Protostuff 1.6.0 序列化反序列化 -> 耗时 : " + (System.currentTimeMillis() - start4) + " , 长度 : " + sum4);
    }
}

测试结果

JDK 1.8 序列化反序列化 -> 耗时 : 2970 , 长度 : 21989111
Kryo 4.0.2 序列化反序列化 -> 耗时 : 451 , 长度 : 5472470
Hessian 4.0.60 序列化反序列化 -> 耗时 : 1397 , 长度 : 7888970
Protostuff 1.6.0 序列化反序列化 -> 耗时 : 706 , 长度 : 2155925
工具 序列化后数据长度 耗时ms
JDK 1.8 21989111 2970
Kryo 4.0.2 5472470 451
Hessian 4.0.60 7888970 1397
Protostuff 1.6.0 2155925 706

初步结论

耗时:JDK > Hessian > Protostuff > Kryo

数据长度:JDK > Hessian > Kryo > Protostuff

从测试结果来看,序列化工具 Protostuff 以及 Kryo 在耗时及存储上看均优于 JDK 以及 Hessian,相应的可以提供更高的计算性能以及更少的存储空间,选型过程中应当优先考虑。其次,衡量性能与存储,可根据场景选取 Protostuff 或 Kryo。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

像计算机科学家一样思考Python (第2版)

像计算机科学家一样思考Python (第2版)

[美] 艾伦 B. 唐尼 / 赵普明 / 人民邮电出版社 / 2016-7 / 49.00

本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程。贯穿全书的主体是如何思考、设计、开发的方法,而具体的编程语言,只是提供了一个具体场景方便介绍的媒介。 全书共21章,详细介绍Python语言编程的方方面面。本书从基本的编程概念开始讲起,包括语言的语法和语义,而且每个编程概念都有清晰的定义,引领读者循序渐进地学习变量、表达式、语句、函数和数据结构。书中还探讨了如何处理文件和......一起来看看 《像计算机科学家一样思考Python (第2版)》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具