最近在做一个高并发的 API 服务,JSON 序列化成了性能瓶颈。标准库虽然稳定可靠,但在压测时 CPU 占用居高不下。于是我决定做一次彻底的 JSON 库性能对比,看看市面上这些号称"高性能"的库到底有多少真本事。

参赛选手

这次对比选了 4 个主流的 JSON 库,外加标准库作为基准:

特点
encoding/json标准库,稳定可靠,开箱即用
goccy/go-json号称零反射的高性能方案
json-iterator/go滴滴开源,API 兼容标准库
mailru/easyjson代码生成方案,需要额外构建步骤

另外还测试了 tidwall/pretty 这个专门做 JSON 格式化的库。

测试环境

  • Go 1.25.5
  • macOS / Apple Silicon (M 系列芯片)
  • 8 核 CPU

测试代码在这里:tenfyzhong/json-benchmark

编码性能:谁序列化最快?

先看编码(Marshal)性能。我准备了两组测试数据:

  • 小型结构体:大约 10 个字段,模拟常见的 API 响应
  • 大型结构体:50+ 个字段,包含嵌套结构,模拟复杂业务对象

小型结构体编码

排名耗时 (ns/op)内存分配加速比
🥇easyjson342.60912 B3.46x
🥈json-iterator383.201032 B3.10x
🥉go-json883.101024 B1.34x
4encoding/json1187.001024 B1.00x

大型结构体编码

排名耗时 (ns/op)内存分配加速比
🥇easyjson31863070 B3.88x
🥈json-iterator33785277 B3.66x
🥉go-json74895270 B1.65x
4encoding/json123515273 B1.00x

结论:easyjson 和 json-iterator 在编码场景打得难解难分,都能达到标准库 3 倍以上的性能。go-json 表现中规中矩。

解码性能:反序列化谁更强?

解码(Unmarshal)通常比编码更复杂,因为涉及到 JSON 解析和类型转换。

小型结构体解码

排名耗时 (ns/op)内存分配加速比
🥇easyjson452.20168 B3.80x
🥈go-json694.60744 B2.47x
🥉json-iterator1059.00640 B1.62x
4encoding/json1718.00472 B1.00x

大型结构体解码

排名耗时 (ns/op)内存分配加速比
🥇easyjson53622944 B3.07x
🥈go-json70718130 B2.32x
🥉json-iterator95117162 B1.73x
4encoding/json164353712 B1.00x

有意思的发现:在解码场景,go-json 反超了 json-iterator!这说明不同库的优化策略确实不同:json-iterator 更擅长编码,go-json 更擅长解码。

JSON 格式化:别小看这个场景

如果你的服务需要做 JSON 美化输出(比如调试接口、日志记录),tidwall/pretty 这个专门库值得一看:

Pretty Print(格式化)

场景pretty.Prettyjson.Indent加速比
小型 JSON317.1 ns894.7 ns2.82x
大型 JSON3389 ns9883 ns2.92x

Compact(压缩)

场景pretty.Uglyjson.Compact加速比
小型 JSON219.2 ns1004 ns4.58x
大型 JSON2673 ns12475 ns4.67x

接近 5 倍的性能提升,这在需要频繁处理 JSON 格式化的场景非常可观。

怎么选?

根据测试结果,我总结了一份选型指南:

追求极致性能:选 easyjson

easyjson 在所有场景都是冠军,但代价是需要代码生成:

# 安装
go install github.com/mailru/easyjson/...@latest

# 生成代码
easyjson -all your_types.go

适合场景:

  • 高频调用的核心 API
  • 对性能有明确要求的服务
  • 结构体定义相对稳定

想要性能提升又不想改构建流程:选 json-iterator 或 go-json

这两个库都是"即插即用"的,API 兼容标准库:

// json-iterator
import jsoniter "github.com/json-iterator/go"
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(v)

// go-json
import gojson "github.com/goccy/go-json"
gojson.Marshal(v)

选择建议:

  • 编码多于解码 → json-iterator
  • 解码多于编码 → go-json
  • 不确定 → 都试试,实测为准

只是想让 JSON 输出好看点:选 pretty

import "github.com/tidwall/pretty"

formatted := pretty.Pretty(jsonBytes)
compacted := pretty.Ugly(jsonBytes)

最后

标准库慢是慢了点,但它的稳定性和兼容性是最好的。如果性能不是瓶颈,用标准库完全没问题。

性能优化这事儿,还是那句老话:先 profile,再优化。别为了那点理论上的性能提升把代码搞得一团糟。

完整的测试代码和数据在这里:tenfyzhong/json-benchmark