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

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

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

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

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进行序列化。

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

相关推荐
天上掉下来个程小白5 分钟前
HttpClient-03.入门案例-发送POST方式请求
java·spring·httpclient·苍穹外卖
ModestCoder_14 分钟前
将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)
android·java·机器人
a1800793108035 分钟前
软件工程面试题(二十二)
java·面试·软件工程
RainbowSea38 分钟前
4. RabbitMQ 发布确认的配置详细说明
java·消息队列·rabbitmq
robin_suli1 小时前
Spring事务的传播机制
android·java·spring
青云交1 小时前
Java 大视界 -- Java 大数据在智能电网电力市场交易数据分析与策略制定中的关键作用(162)
java·大数据·数据分析·交易策略·智能电网·java 大数据·电力市场交易
m0Java门徒1 小时前
Java 递归全解析:从原理到优化的实战指南
java·开发语言
云徒川1 小时前
【设计模式】原型模式
java·设计模式·原型模式
张张张3121 小时前
4.2学习总结 Java:list系列集合
java·学习
KATA~2 小时前
解决MyBatis-Plus枚举映射错误:No enum constant问题
java·数据库·mybatis