1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
package main
import (
"bytes"
"encoding/gob"
"encoding/json"
"fmt"
)
func main() {
fmt.Println("=== gob 序列化比 JSON 大的原因分析 ===\n")
// 1. 类型信息开销
analyzeTypeInformation()
// 2. 字段名存储
analyzeFieldNames()
// 3. 编码格式差异
analyzeEncodingFormat()
// 4. 实际案例分析
realWorldExample()
}
func analyzeTypeInformation() {
fmt.Println("1. 类型信息开销")
fmt.Println(" gob 需要在序列化数据中包含完整的类型定义信息")
type SimpleStruct struct {
Name string
Age int
}
data := SimpleStruct{Name: "test", Age: 25}
// JSON 序列化
jsonData, _ := json.Marshal(data)
// gob 序列化
var gobBuf bytes.Buffer
gob.NewEncoder(&gobBuf).Encode(data)
fmt.Printf(" 简单结构体: JSON=%d字节, gob=%d字节\n", len(jsonData), gobBuf.Len())
fmt.Printf(" JSON内容: %s\n", string(jsonData))
fmt.Printf(" gob包含类型定义: SimpleStruct, Name string, Age int\n\n")
}
func analyzeFieldNames() {
fmt.Println("2. 字段名存储方式")
fmt.Println(" gob 存储完整的字段名,而 JSON 在每个对象中重复字段名")
type Person struct {
FirstName string
LastName string
Email string
}
// 单个对象
single := Person{FirstName: "John", LastName: "Doe", Email: "john@example.com"}
jsonSingle, _ := json.Marshal(single)
var gobSingle bytes.Buffer
gob.NewEncoder(&gobSingle).Encode(single)
fmt.Printf(" 单个对象: JSON=%d字节, gob=%d字节\n", len(jsonSingle), gobSingle.Len())
// 多个对象数组
multiple := []Person{
{FirstName: "John", LastName: "Doe", Email: "john@example.com"},
{FirstName: "Jane", LastName: "Smith", Email: "jane@example.com"},
{FirstName: "Bob", LastName: "Johnson", Email: "bob@example.com"},
}
jsonMultiple, _ := json.Marshal(multiple)
var gobMultiple bytes.Buffer
gob.NewEncoder(&gobMultiple).Encode(multiple)
fmt.Printf(" 三个对象: JSON=%d字节, gob=%d字节\n", len(jsonMultiple), gobMultiple.Len())
fmt.Printf(" JSON 重复字段名,gob 只存储一次类型定义\n\n")
}
func analyzeEncodingFormat() {
fmt.Println("3. 编码格式差异")
// 整数编码
fmt.Println(" 整数编码:")
numbers := []int{0, 1, 127, 128, 255, 256, 65535, 65536}
for _, num := range numbers {
jsonData, _ := json.Marshal(num)
var gobBuf bytes.Buffer
gob.NewEncoder(&gobBuf).Encode(num)
fmt.Printf(" %d: JSON=%d字节, gob=%d字节\n", num, len(jsonData), gobBuf.Len())
}
// 字符串编码
fmt.Println(" 字符串编码:")
strings := []string{"", "a", "hello", "这是中文"}
for _, str := range strings {
jsonData, _ := json.Marshal(str)
var gobBuf bytes.Buffer
gob.NewEncoder(&gobBuf).Encode(str)
fmt.Printf(" \"%s\": JSON=%d字节, gob=%d字节\n", str, len(jsonData), gobBuf.Len())
}
fmt.Println()
}
func realWorldExample() {
fmt.Println("4. 实际案例分析")
// 模拟你的测试文件中的数据结构
type PLineData struct {
ID int `json:"id"`
BusinessCode string `json:"business_code"`
BusinessName string `json:"business_name"`
FactorCode string `json:"factor_code"`
FactorName string `json:"factor_name"`
PlatformName string `json:"platform_name"`
WorkType int `json:"work_type"`
PCode string `json:"p_code"`
PName string `json:"p_name"`
ProductionLineCode string `json:"production_line_code"`
ProductionLineName string `json:"production_line_name"`
IsEnable int `json:"is_enable"`
IsDelete int `json:"is_delete"`
CreateTime string `json:"create_time"`
UpdateTime string `json:"update_time"`
PlineStatus int `json:"pline_status"`
PlatformCode string `json:"platform_code"`
}
// 创建测试数据
data := PLineData{
ID: 389,
BusinessCode: "P",
BusinessName: "POI",
FactorCode: "P_1003",
FactorName: "上车点_区域型",
PlatformName: "xx平台",
WorkType: 2,
PCode: "P_110093",
PName: "POI上车点区域型",
ProductionLineCode: "101_688_1",
ProductionLineName: "打车上车点产线-打车上车点产线1-区域型上车点",
IsEnable: 1,
IsDelete: 0,
CreateTime: "2025-01-20 18:42:15",
UpdateTime: "2025-01-20 18:42:15",
PlineStatus: 1,
PlatformCode: "11",
}
jsonData, _ := json.Marshal(data)
var gobBuf bytes.Buffer
gob.NewEncoder(&gobBuf).Encode(data)
fmt.Printf(" 产线数据结构: JSON=%d字节, gob=%d字节\n", len(jsonData), gobBuf.Len())
fmt.Printf(" gob 额外开销: %d字节 (%.1f%%)\n",
gobBuf.Len()-len(jsonData),
float64(gobBuf.Len()-len(jsonData))/float64(len(jsonData))*100)
fmt.Println("\n=== gob 额外开销的组成 ===")
fmt.Println("1. 类型定义信息: 包含结构体名称和所有字段的类型信息")
fmt.Println("2. 字段名称: 完整的字段名存储")
fmt.Println("3. 类型标识符: 用于标识不同的数据类型")
fmt.Println("4. 长度前缀: 变长编码的长度信息")
fmt.Println("5. 版本信息: gob 格式的版本标识")
fmt.Println("\n=== 何时 gob 更有优势 ===")
fmt.Println("1. 大量相同结构的数据: 类型信息只需存储一次")
fmt.Println("2. 复杂嵌套结构: gob 的二进制格式更紧凑")
fmt.Println("3. Go 程序间通信: 无需解析,直接反序列化")
fmt.Println("4. 保持类型安全: 编译时类型检查")
}
|