JSON序列化慢的主因是json.Marshal反射开销大,字段多、嵌套深或含map/slice时更明显;应精简结构体、用匿名struct或生成工具如easyjson,流式写入优先选json.Encoder,时间字段需自定义类型实现序列化方法。
JSON序列化慢,先看是不是用了
直接序列化结构体字段太多
Go 默认的
会反射遍历所有可导出字段,字段越多、嵌套越深,性能越差。尤其当结构体里混着
或大 slice 时,反射开销会明显拖慢。
实操建议:
用
前确认结构体是否精简——删掉不用序列化的字段,或加
忽略
避免在 hot path(比如 HTTP handler 内)反复构造含大量字段的 struct 实例
如果只是输出固定几个字段,直接构建 map 或用
匿名结构体,比复用大 struct 更快
需要高频 JSON 序列化?考虑用
或
替代原生
原生
包依赖反射,每次调用都做类型检查和字段查找;
则在编译期生成专用序列化函数,绕过反射,实测吞吐量常提升 2–5 倍。
但要注意:
立即学习
“
go语言免费学习笔记(深入)
”;
必须给 struct 加
注释,并运行
生成代码
生成的文件要和源码一起编译,不能只改 struct 就完事——漏掉重新生成会导致行为不一致
对嵌套泛型支持弱,
或
字段仍会 fallback 到反射,别指望它全包圆
比
更适合流式写入
当你往
或文件写 JSON,别先
成
再 write——这多一次内存拷贝,还可能触发 GC 压力。
正确做法是直接用
:
它把序列化结果直接写入底层
,零中间分配
配合
还能边序列化边推送(适合长 JSON 流或 SSE)
注意:如果
是
,得确保没提前写 header,否则
可能 panic
时间字段序列化出错?别硬套
默认格式
Go 的
默认 JSON 序列化是 RFC3339 字符串,带毫秒和时区,但很多前端或老系统只认
或 Unix timestamp。直接改
字段 tag 很容易漏掉
配套逻辑,导致反序列化失败。
稳妥方案:
定义自定义类型封装
,实现
和
或者用
延迟解析,避免在结构体层强绑定格式
千万别在 struct tag 里写
然后以为能自动转字符串——它只对数字/布尔生效,对
无效
真正卡住性能的往往不是 JSON 本身,而是没意识到
的反射成本藏在哪一层;生成代码工具又容易漏掉重新生成步骤;时间字段看着简单,一动 tag 就埋下反序列化失败的坑。
json.Marshaljson.Marshalmap[string]interface{}json.Marshaljson:"-"struct{ A, B string }easyjsonffjsonjsonjsoneasyjson//easyjson:jsoneasyjson -all xxx.goeasyjsonmap[any]anyinterface{}json.Encoderjson.Marshalhttp.ResponseWriterjson.Marshal[]bytejson.NewEncoder(w io.Writer)Writerhttp.Flusherwhttp.ResponseWriterEncodetime.Timetime.Time"2006-01-02"TimeUnmarshalJSONtime.TimeMarshalJSONUnmarshalJSONjson.RawMessagejson:"created_at,string"time.Timejson.Marshal