序列化与反序列化及不同序列化方式的性能对比

在现代分布式系统中,序列化和反序列化是不可或缺的环节。它们用于将对象转换为可传输的字节流,并在接收端重建对象。本文将探讨几种常见的序列化方式,包括JSON、Java原生序列化和Protobuf,并通过实例代码进行性能对比。

序列化方式简介
  1. JSON: 简单、可读性强,但性能和体积上相对较差。
  2. Java原生序列化: Java内置,使用简单,但体积较大且性能一般。
  3. Protobuf (Protocol Buffers): Google开发的高效序列化框架,性能和体积优于JSON和Java原生序列化。
实例代码

我们将使用一个简单的类 Cat 进行序列化和反序列化测试。Cat 类包含两个属性:name 和 age。

java 复制代码
import java.io.*;

class Cat implements Serializable {
    private String name;
    private int age;

    // Constructors, getters, and setters

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // toString method
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
JSON序列化和反序列化

我们使用 Jackson 库进行JSON序列化和反序列化。

java 复制代码
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonSerialization {
    private static ObjectMapper objectMapper = new ObjectMapper();

    public static String serialize(Cat cat) throws IOException {
        return objectMapper.writeValueAsString(cat);
    }

    public static Cat deserialize(String json) throws IOException {
        return objectMapper.readValue(json, Cat.class);
    }
}

Java原生序列化和反序列化

java 复制代码
public class NativeSerialization {
    public static byte[] serialize(Cat cat) throws IOException {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(bos)) {
            oos.writeObject(cat);
            return bos.toByteArray();
        }
    }

    public static Cat deserialize(byte[] data) throws IOException, ClassNotFoundException {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(data);
             ObjectInputStream ois = new ObjectInputStream(bis)) {
            return (Cat) ois.readObject();
        }
    }
}
Protobuf序列化和反序列化

首先,定义Protobuf的 .proto 文件:

java 复制代码
syntax = "proto3";

message Cat {
    string name = 1;
    int32 age = 2;
}

生成Java类后:

java 复制代码
import com.google.protobuf.InvalidProtocolBufferException;
import example.CatProto.Cat;

public class ProtobufSerialization {
    public static byte[] serialize(Cat cat) {
        return cat.toByteArray();
    }

    public static Cat deserialize(byte[] data) throws InvalidProtocolBufferException {
        return Cat.parseFrom(data);
    }
}
性能对比

我们通过以下代码进行性能测试:

java 复制代码
import java.io.IOException;
import java.util.Arrays;

public class SerializationPerformanceTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Cat cat = new Cat("Whiskers", 3);

        // JSON
        long jsonStart = System.nanoTime();
        String json = JsonSerialization.serialize(cat);
        Cat jsonCat = JsonSerialization.deserialize(json);
        long jsonEnd = System.nanoTime();
        System.out.println("JSON time: " + (jsonEnd - jsonStart));

        // Native
        long nativeStart = System.nanoTime();
        byte[] nativeData = NativeSerialization.serialize(cat);
        Cat nativeCat = NativeSerialization.deserialize(nativeData);
        long nativeEnd = System.nanoTime();
        System.out.println("Native time: " + (nativeEnd - nativeStart));

        // Protobuf
        example.CatProto.Cat protoCat = example.CatProto.Cat.newBuilder().setName("Whiskers").setAge(3).build();
        long protoStart = System.nanoTime();
        byte[] protoData = ProtobufSerialization.serialize(protoCat);
        example.CatProto.Cat protoCatDeserialized = ProtobufSerialization.deserialize(protoData);
        long protoEnd = System.nanoTime();
        System.out.println("Protobuf time: " + (protoEnd - protoStart));
    }
}
结论

根据测试结果,Protobuf的序列化和反序列化性能优于JSON和Java原生序列化。虽然JSON的可读性强,但在性能和体积上,Protobuf更具优势。因此,在对性能和体积有较高要求的场景下,推荐使用Protobuf进行序列化。

通过以上实例代码和测试结果,我们可以更好地理解不同序列化方式的优缺点,并根据具体需求选择合适的序列化方式。

相关推荐
云和数据.ChenGuang1 小时前
print(f“a+b=“,result) print(f“a+b={result}“)区别
java·前端·人工智能·python·深度学习
2601_962885721 小时前
如何用 Python 算最大回撤和回撤恢复期?
java·数据库·python
毕业设计7032 小时前
(免费领源码)SSM董家湾线上点餐系统04682- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
java·redis·mysql·tomcat·maven·mybatis·ssm
Q26433650232 小时前
【有源码】基于SpringBoot+Vue的居民健康体检与慢病干预管理系统-面向智慧医疗的体检预约与健康知识服务平台
java·vue.js·spring boot·mysql·毕业设计·javaweb·课程设计
悠仁さん3 小时前
非类型模板参数的特化与偏特化
java·数据结构·算法
鬼手点金3 小时前
上下文:Agent 的眼睛
java·前端·人工智能·git·深度学习
171320330计算机毕设编程3 小时前
计算机毕业设计 基于Hadoop的新能源汽车发展前景分析 LW PPT
java·大数据·hadoop·python·算法·随机森林·线性回归
技术小结-李爽3 小时前
【工具】怎么在终端中启动springboot项目?
java·spring boot·后端·maven
Shaoshing3 小时前
消息发送
java·开发语言