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

在现代分布式系统中,序列化和反序列化是不可或缺的环节。它们用于将对象转换为可传输的字节流,并在接收端重建对象。本文将探讨几种常见的序列化方式,包括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进行序列化。

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

相关推荐
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸5 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象5 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了6 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·6 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王6 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康7 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神7 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342737 小时前
Java实现离线身份证号码OCR识别
java·开发语言