首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >开源项目|2000行代码的 `JSON` 库

开源项目|2000行代码的 `JSON` 库

作者头像
用户1904552
发布2025-06-30 09:32:47
发布2025-06-30 09:32:47
15300
代码可运行
举报
文章被收录于专栏:周末程序猿周末程序猿
运行总次数:0
代码可运行

周末程序猿

鹅厂程序猿,专注后台开发和人工智能领域~~

101篇原创内容

公众号

虽然一直在开发中使用 JSON 解析,但是如何高效的从 0 实现一个 JSON 解析,一直还未尝试,花了几个周末的时间用 golang 实现 sjson。 github:https://github.com/linkxzhou/sjson

功能

sjson 是一个高性能的 Go 语言 JSON 解析库,提供了高效的 JSON 编码和解码功能。它采用直接解码技术,无需中间 Value 对象,从而提高解析效率。

架构

图片
图片

特性

  • 简单易用的 API,与标准库 encoding/json 接口兼容
  • 高性能直接解码器实现,无需中间 Value 对象
  • 支持基本的 JSON 数据类型:null、布尔值、数字、字符串、数组和对象
  • 支持结构体与 JSON 的相互转换,支持 json 标签
  • 提供流式解析功能,可从字符串或 Reader 中解析 JSON
  • 使用对象池和内存复用技术,减少内存分配和 GC 压力
  • 针对常见类型和场景进行了性能优化
  • 代码精简,主要逻辑代码 2000 行

安装

代码语言:javascript
代码运行次数:0
运行
复制
go get github.com/linkxzhou/sjson

性能对比

sjson 库的性能目标是接近或超过最新 v2 标准库 encoding/json,同时提供更简洁的 API 和更好的可扩展性。

1. Unmarshal 性能对比图(ns/op)

图片
图片

2. Unmarshal 吞吐量对比图(MB/s)

图片
图片

3. Marshal 性能对比图(ns/op)

图片
图片

4. Marshal 吞吐量对比图(MB/s)

图片
图片

运行测试

代码语言:javascript
代码运行次数:0
运行
复制
# 运行所有测试
go test -v ./...

# 运行测试并生成覆盖率报告
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# 运行基准测试
go test -bench=. -benchmem ./...

# 运行代码质量检查
golangci-lint run

使用示例

解析 JSON 字符串

代码语言:javascript
代码运行次数:0
运行
复制
package main

import (
"fmt"
"github.com/linkxzhou/sjson"
)

func main() {
// 解析 JSON 到 interface{}
var data interface{}
 jsonStr := `{"name":"张三","age":30,"skills":["Go","Python"]}`
 err := sjson.Unmarshal([]byte(jsonStr), &data)
if err != nil {
  fmt.Println("解析错误:", err)
return
 }
 fmt.Printf("%+v\n", data)

// 解析 JSON 到结构体
type Person struct {
  Name   string   `json:"name"`
  Age    int      `json:"age"`
  Skills []string`json:"skills"`
 }

var person Person
 err = sjson.Unmarshal([]byte(jsonStr), &person)
if err != nil {
  fmt.Println("解析错误:", err)
return
 }
 fmt.Printf("%+v\n", person)
}

生成 JSON 字符串

代码语言:javascript
代码运行次数:0
运行
复制
package main

import (
"fmt"
"github.com/linkxzhou/sjson"
)

func main() {
// 从结构体生成 JSON
 person := struct {
  Name   string   `json:"name"`
  Age    int      `json:"age"`
  Skills []string`json:"skills"`
 }{
  Name:   "李四",
  Age:    ,
  Skills: []string{"Java", "C++"},
 }

 data, err := sjson.Marshal(person)
if err != nil {
  fmt.Println("编码错误:", err)
return
 }
 fmt.Println(string(data))
}

从 Reader 解析 JSON

代码语言:javascript
代码运行次数:0
运行
复制
package main

import (
"fmt"
"github.com/linkxzhou/sjson"
"strings"
)

func main() {
// 从 Reader 解析 JSON
 jsonReader := strings.NewReader(`{"success":true,"data":{"items":[1,2,3]}}`)

var result struct {
  Success bool`json:"success"`
  Data    struct {
   Items []int`json:"items"`
  } `json:"data"`
 }

 err := sjson.UnmarshalFromReader(jsonReader, &result)
if err != nil {
  fmt.Println("解析错误:", err)
return
 }

 fmt.Printf("success: %v, items: %v\n", result.Success, result.Data.Items)
}

自定义配置

代码语言:javascript
代码运行次数:0
运行
复制
package main

import (
"fmt"
"github.com/linkxzhou/sjson"
)

func main() {
// 使用自定义配置
 config := sjson.Config{
  SortMapKeys: true, // 对 map 的键进行排序
 }

 data := map[string]interface{}{
"z": ,
"a": ,
"m": ,
 }

// 使用自定义配置进行编码
 jsonBytes, _ := sjson.MarshalWithConfig(data, config)
 fmt.Println(string(jsonBytes)) // 输出键已排序的 JSON
}

API 文档

解码函数

  • Unmarshal(data []byte, v interface{}) error - 将 JSON 字节切片解析为 Go 对象
  • UnmarshalWithConfig(data []byte, v interface{}, config Config) error - 使用自定义配置解析 JSON
  • UnmarshalFromReader(r io.Reader, v interface{}) error - 从 Reader 解析 JSON
  • UnmarshalFromReaderWithConfig(r io.Reader, v interface{}, config Config) error - 使用自定义配置从 Reader 解析 JSON

编码函数

  • Marshal(v interface{}) ([]byte, error) - 将 Go 对象编码为 JSON 字节切片
  • MarshalString(v interface{}) (string, error) - 将 Go 对象编码为 JSON 字符串
  • MarshalWithConfig(v interface{}, config Config) ([]byte, error) - 使用自定义配置编码 JSON

配置选项

  • Config - 用于配置 JSON 解析和编码的行为
    • SortMapKeys - 控制对象和 map 的键是否排序,默认不排序

性能优化

sjson 库采用了多种性能优化技术:

  1. 直接解码:无需中间 Value 对象,直接解码到目标 Go 对象
  2. 对象池:使用 sync.Pool 减少内存分配
  3. 预分配内存:为数组和切片预分配适当容量
  4. 类型特化:针对常见类型提供专用编码/解码路径
  5. 常量缓存:预生成常用数字和字符串常量
  6. 减少反射:尽可能减少反射操作,提高性能
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 周末程序猿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 功能
  • 架构
  • 特性
  • 安装
  • 性能对比
    • 1. Unmarshal 性能对比图(ns/op)
    • 2. Unmarshal 吞吐量对比图(MB/s)
    • 3. Marshal 性能对比图(ns/op)
    • 4. Marshal 吞吐量对比图(MB/s)
    • 运行测试
  • 使用示例
    • 解析 JSON 字符串
    • 生成 JSON 字符串
    • 从 Reader 解析 JSON
    • 自定义配置
  • API 文档
    • 解码函数
    • 编码函数
    • 配置选项
  • 性能优化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档