Go 1.27 JSON/v2 转正:反序列化提速,结构体切片序列化实测慢约 1.5 倍
Go 1.27 于 2026-08-19 发布。这个版本里,encoding/json/v2 与 encoding/json/jsontext 不再需要 GOEXPERIMENT=jsonv2。v2 的默认行为更严格:拒绝非法 UTF-8 字符串,拒绝重复的对象成员名。原有的 encoding/json(v1)改由 v2 实现支撑,反序列化更快,同时对 v1 的行为保持兼容。
v2 API 与 jsontext
v2 提供这些入口:
Marshal
MarshalWrite
MarshalEncode
Unmarshal
UnmarshalRead
UnmarshalDecode
它们全部接受可变参数的 Options,用来精细配置序列化和反序列化行为。
jsontext 更底层。Encoder 和 Decoder 直接操作 JSON 的 Token 与 Value 序列,内部维护状态机。
兼容性回退
如果新实现在项目中触发了兼容性问题,可以通过 GOEXPERIMENT=nojsonv2 在构建期切回原始的 v1 实现:
GOEXPERIMENT=nojsonv2
该开关预计会在未来版本中移除。v2 转正后,GOEXPERIMENT=jsonv2 不再需要开启。对于现有 v1 调用,迁移不是强制的;只有遇到 v2 默认严格行为或性能回归时,才需要评估构建期回退。
基准:快一倍,还是慢 1.5 倍?
这是对 Go 1.27 的 JSON 包(包括 encoding/json/v2)做的一次基准测试。使用 v2 时反序列化更快,但发现对结构体切片做序列化反而慢了 1.5 倍,这与发布说明中的性能说法相悖。
基准结果可以拆成两个方向:
- 反序列化更快,且有显著提升。
- 序列化性能与此前基本持平,但结构体切片场景出现约 1.5 倍的回退。
错误信息的具体文本可能会有变化,但整体的序列化 / 反序列化行为保持向后兼容,v1 API 会继续得到支持,用户不需要被迫迁移。若负载以反序列化为主,v2 的收益更直接;若大量路径是序列化 []struct,升级后需要单独关注这一场景。
严格默认行为也会影响外部输入。依赖重复对象成员名或非法 UTF-8 字符串的旧数据,在 v2 下会被拒绝,需要在入口处清洗,或通过 Options 调整行为。
同一周其他动向
- Go 1.27.1:修复 cgo、编译器、运行时、
go fix命令,以及database/sql、debug/elf、encoding/json、net/http、os、simd和simd/archsimd等包的问题。 - Go 1.26.8:修复 cgo、编译器、运行时,以及
debug/elf和os包的问题。 - HTTP/2 原生移入
net/http的长期工程被标记为“已完成”,x/net/http2走向弃用。 quic-go0.62 支持 RFC 9218 流优先级。- Go 1.27 新增
goroutineleakprofile,可定位永久阻塞在 channel 或同步原语上的 goroutine,即使生产环境也能用,复用垃圾回收的可达性追踪。 go mod tidy现在会自动把go.mod中多个零散的require块合并成标准的两块结构(直接依赖 + 间接依赖),前提是模块声明的 Go 版本在 1.27 或以上。