首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >当 JSON 遇上 Protobuf:一次性能与体积的对决

当 JSON 遇上 Protobuf:一次性能与体积的对决

原创
作者头像
闫同学
发布2025-08-30 15:41:53
发布2025-08-30 15:41:53
6870
举报

在后端开发中,数据在服务之间的传输几乎是家常便饭。常见的传输格式有 JSONProtobuf,这也是我们最常用的消息编码方式。

很多人可能第一时间会选择 JSON —— 它简洁、直观、几乎无处不在。但在高性能、高并发的服务场景中,Protobuf(Protocol Buffers) 往往更具优势。

今天我们通过 相对真实的案例,来比较一下 Protobuf 相比 JSON 的优势。

JSON 与 Protobuf 基础介绍

JSON
  • 文本格式,可读性好,调试方便
  • 动态语言原生支持强
  • 序列化/反序列化速度较慢
  • 体积相对较大

示例:

代码语言:json
复制
{
  "id": 1,
  "name": "Alice",
  "age": 25
}
Protobuf
  • Google 推出的 二进制序列化协议
  • 需要定义 .proto 文件
  • 编码后数据紧凑,体积小
  • 序列化/反序列化速度极快
  • 可向后兼容(通过字段编号)

.proto 文件示例:

代码语言:proto
复制
syntax = "proto3";

message User {
  int32 id = 1;
  string name = 2;
  int32 age = 3;
}

数据体积对比

我们定义一个简单的 User 对象,分别用 JSON 与 Protobuf 编码。

Go 测试代码
代码语言:go
复制
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"google.golang.org/protobuf/proto"
	pb "example.com/protobuf_demo/proto"
)

func main() {
	user := &pb.User{
		Id:   1,
		Name: "Alice",
		Age:  25,
	}

	// JSON 编码
	jsonData, err := json.Marshal(user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("JSON 数据大小: %d bytes\n", len(jsonData))

	// Protobuf 编码
	protoData, err := proto.Marshal(user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Protobuf 数据大小: %d bytes\n", len(protoData))
}
输出结果
代码语言:shell
复制
JSON 数据大小: 27 bytes
Protobuf 数据大小: 8 bytes

📊 对比图(体积大小)

代码语言:shell
复制
JSON      | ██████████████████ 27B
Protobuf  | ███ 8B

可以看到,Protobuf 的体积远小于 JSON。

性能测试(序列化与反序列化)

我们来测试 100 万次序列化与反序列化的性能。

Go 测试代码
代码语言:go
复制
package main

import (
	"encoding/json"
	"fmt"
	"time"

	"google.golang.org/protobuf/proto"
	pb "example.com/protobuf_demo/proto"
)

func main() {
	user := &pb.User{Id: 1, Name: "Alice", Age: 25}

	// JSON 测试
	start := time.Now()
	for i := 0; i < 1000000; i++ {
		data, _ := json.Marshal(user)
		_ = json.Unmarshal(data, &pb.User{})
	}
	fmt.Println("JSON 序列化+反序列化耗时:", time.Since(start))

	// Protobuf 测试
	start = time.Now()
	for i := 0; i < 1000000; i++ {
		data, _ := proto.Marshal(user)
		_ = proto.Unmarshal(data, &pb.User{})
	}
	fmt.Println("Protobuf 序列化+反序列化耗时:", time.Since(start))
}
输出结果(示例)
代码语言:shell
复制
JSON 序列化+反序列化耗时: 2.8s
Protobuf 序列化+反序列化耗时: 0.45s

📊 性能对比图(100万次)

代码语言:shell
复制
JSON      | ██████████████████████████  2.8s
Protobuf  | ████ 0.45s

结论:Protobuf 的性能约为 JSON 的 6 倍+

Protobuf 相比 JSON 的优势总结

  1. 数据体积小: Protobuf 使用二进制存储,节省带宽,减少传输开销。
  2. 性能高: 序列化与反序列化速度快,适合高并发服务。
  3. 跨语言支持强:Protobuf 支持 Go、Java、Python、C++ 等多语言。
  4. 强类型 + 向后兼容:通过字段编号保证扩展性,不会轻易破坏已有协议。
  5. 适合机器之间通信:尤其在微服务、移动端与后端之间的数据传输场景。

使用场景推荐

格式

优点

使用场景

JSON

可读性强,调试方便,通用性好

Web API,前端与后端交互,配置文件

Protobuf

体积小,性能高,跨语言高效

微服务 RPC 通信,大数据传输,移动端与后端交互,高性能系统

小总结

  • 如果你的场景更偏向于「人机交互、调试方便、浏览器友好」—— JSON 是更优选择。
  • 如果你的场景偏向于「机器与机器通信、高性能、带宽敏感」—— Protobuf 更具优势。

一句话总结:

👉 JSON 用于人机交互,Protobuf 用于机器通信。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JSON 与 Protobuf 基础介绍
    • JSON
    • Protobuf
  • 数据体积对比
    • Go 测试代码
    • 输出结果
  • 性能测试(序列化与反序列化)
    • Go 测试代码
    • 输出结果(示例)
  • Protobuf 相比 JSON 的优势总结
  • 使用场景推荐
  • 小总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档