
在后端开发中,数据在服务之间的传输几乎是家常便饭。常见的传输格式有 JSON 和 Protobuf,这也是我们最常用的消息编码方式。
很多人可能第一时间会选择 JSON —— 它简洁、直观、几乎无处不在。但在高性能、高并发的服务场景中,Protobuf(Protocol Buffers) 往往更具优势。
今天我们通过 相对真实的案例,来比较一下 Protobuf 相比 JSON 的优势。
示例:
{
"id": 1,
"name": "Alice",
"age": 25
}.proto 文件.proto 文件示例:
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
int32 age = 3;
}我们定义一个简单的 User 对象,分别用 JSON 与 Protobuf 编码。
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))
}JSON 数据大小: 27 bytes
Protobuf 数据大小: 8 bytes📊 对比图(体积大小)
JSON | ██████████████████ 27B
Protobuf | ███ 8B可以看到,Protobuf 的体积远小于 JSON。
我们来测试 100 万次序列化与反序列化的性能。
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))
}JSON 序列化+反序列化耗时: 2.8s
Protobuf 序列化+反序列化耗时: 0.45s📊 性能对比图(100万次)
JSON | ██████████████████████████ 2.8s
Protobuf | ████ 0.45s结论:Protobuf 的性能约为 JSON 的 6 倍+。
格式 | 优点 | 使用场景 |
|---|---|---|
JSON | 可读性强,调试方便,通用性好 | Web API,前端与后端交互,配置文件 |
Protobuf | 体积小,性能高,跨语言高效 | 微服务 RPC 通信,大数据传输,移动端与后端交互,高性能系统 |
一句话总结:
👉 JSON 用于人机交互,Protobuf 用于机器通信。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。