用 ANSI C 编写的高性能 JSON 库。
快速:在现代 CPU 上每秒可以读取或写入 GB 级的 JSON 数据。
便携:符合 ANSI C (C89) 的跨平台兼容性。
严格:符合 RFC 8259 JSON 标准,确保严格的数字格式和 UTF-8 验证。
可扩展:提供允许注释、尾随逗号、NaN/Inf 和自定义内存分配器的选项。
准确度:可以准确读写int64
、 uint64
、 double
数。
灵活:支持无限的 JSON 嵌套级别、 u0000
个字符和非空终止字符串。
Manipulation :支持使用 JSON Pointer、JSON Patch 和 JSON Merge Patch 进行查询和修改。
开发人员友好:只需 1 个h
和 1 个c
文件即可轻松集成。
数组或对象存储为数据结构(例如链表),这使得通过索引或键访问元素比使用迭代器慢。
对象中允许有重复的键,并且保留键的顺序。
JSON解析结果是不可变的,需要一个mutable copy
来修改。
基准项目和数据集:yyjson_benchmark
如果大多数 JSON 字段在编译时已知,则 simdjson 的新On Demand
API 速度会更快。该基准测试项目仅检查 DOM API,稍后将添加新的基准测试。
推特.json | 解析(GB/秒) | 字符串化 (GB/s) |
---|---|---|
yyjson(原位) | 1.80 | 1.51 |
yyjson | 1.72 | 1.42 |
simdjson | 1.52 | 0.61 |
萨森 | 1.16 | |
Rapidjson(原位) | 0.77 | |
Rapidjson(utf8) | 0.26 | 0.39 |
.cjson | 0.32 | 0.17 |
詹森 | 0.05 | 0.11 |
推特.json | 解析(GB/秒) | 字符串化 (GB/s) |
---|---|---|
yyjson(原位) | 3.51 | 2.41 |
yyjson | 2.39 | 2.01 |
simdjson | 2.19 | 0.80 |
萨森 | 1.74 | |
Rapidjson(原位) | 0.75 | |
Rapidjson(utf8) | 0.30 | 0.58 |
.cjson | 0.48 | 0.33 |
詹森 | 0.09 | 0.24 |
更多带有交互式图表的基准报告(更新2020-12-12)
平台 | 中央处理器 | 编译器 | 操作系统 | 报告 |
---|---|---|---|---|
英特尔 NUC 8i5 | 酷睿i5-8259U | 2019年MSVC | Windows 10 2004 | 图表 |
英特尔 NUC 8i5 | 酷睿i5-8259U | 铿锵10.0 | 乌班图20.04 | 图表 |
英特尔 NUC 8i5 | 酷睿i5-8259U | 海湾合作委员会9.3 | 乌班图20.04 | 图表 |
AWS EC2 c5a.large | AMD 霄龙 7R32 | 海湾合作委员会9.3 | 乌班图20.04 | 图表 |
AWS EC2 t4g.中 | Graviton2 (ARM64) | 海湾合作委员会9.3 | 乌班图20.04 | 图表 |
苹果 iPhone 12 Pro | A14(ARM64) | 铿锵12.0 | iOS 14 | 图表 |
现代处理器具有:
高指令级并行性
优秀的分支预测器
未对齐内存访问的惩罚较低
具有良好优化器的现代编译器(例如 clang)
const char *json = "{"name":"Mash","star":4,"hits":[2,2,1,3]}";//读取JSON并得到rootyyjson_doc *doc = yyjson_read(json , strlen(json), 0);yyjson_val *root = yyjson_doc_get_root(doc);// 获取 root["name"]yyjson_val *name = yyjson_obj_get(root, "name");printf("name: %sn", yyjson_get_str(name));printf("name length:%dn", (int)yyjson_get_len(name));// 获取root["star "]yyjson_val *star = yyjson_obj_get(root, "star");printf("star: %dn", (int)yyjson_get_int(star));// 获取root["hits"],迭代数组yyjson_val *hits = yyjson_obj_get(root, "hits");size_t idx, max;yyjson_val *hit;yyjson_arr_foreach(hits, idx,最大,命中){printf(“命中%d:%dn”,(int)idx, (int)yyjson_get_int(hit)); }// 释放 docyyjson_doc_free(doc);// 所有函数都接受 NULL 输入,并在出错时返回 NULL。
// 创建可变的docyyjson_mut_doc *doc = yyjson_mut_doc_new(NULL);yyjson_mut_val *root = yyjson_mut_obj(doc);yyjson_mut_doc_set_root(doc, root);//设置root["name"]和root["star"]yyjson_mut_obj_add_str(doc,根,“名称”, "Mash");yyjson_mut_obj_add_int(doc, root, "star", 4);// 将 root["hits"] 设置为数组int hits_arr[] = {2, 2, 1, 3};yyjson_mut_val *hits = yyjson_mut_arr_with_sint32(文档,his_arr,4);yyjson_mut_obj_add_val(文档, root, "hits", hits);// 转为字符串,minifiedconst char *json = yyjson_mut_write(doc, 0, NULL);if (json) {printf("json: %sn", json); // {"name":"Mash","star":4,"hits":[2,2,1,3]}free((void *)json); }// 释放 docyyjson_mut_doc_free(doc);
// 读取 JSON 文件,允许注释和尾随逗号 flg = YYJSON_READ_ALLOW_COMMENTS | YYJSON_READ_ALLOW_TRAILING_COMMAS;yyjson_read_err err;yyjson_doc *doc = yyjson_read_file("/tmp/config.json", flg, NULL, &err);// 迭代根对象if (doc) {yyjson_val *obj = yyjson_doc_get_root(doc);yyjson_obj_iter iter;yyjson_obj_iter_init(obj, &iter);yyjson_val *key, *val;while ((key = yyjson_obj_iter_next(&iter))) {val = yyjson_obj_iter_get_val(key);printf("%s: %sn", yyjson_get_str(key), yyjson_get_type_desc(val)); } } else {printf("读取错误(%u):%s位于位置:%ldn", err.code, err.msg, err.pos); }// 释放 docyyjson_doc_free(doc);
// 将 JSON 文件读取为可变 docyyjson_doc *idoc = yyjson_read_file("/tmp/config.json", 0, NULL, NULL);yyjson_mut_doc *doc = yyjson_doc_mut_copy(idoc, NULL);yyjson_mut_val *obj = yyjson_mut_doc_get_root(doc) ;// 删除 root 中的空值objectyyjson_mut_obj_iter iter;yyjson_mut_obj_iter_init(obj, &iter);yyjson_mut_val *key, *val;while ((key = yyjson_mut_obj_iter_next(&iter))) {val = yyjson_mut_obj_iter_get_val(key);if (yyjson_mut_is_null(val)) {yyjson_mut_obj_iter_remove(&iter); } }// 漂亮地写 json,转义 unicodeyyjson_write_flag flg = YYJSON_WRITE_PRETTY | YYJSON_WRITE_ESCAPE_UNICODE;yyjson_write_err err;yyjson_mut_write_file("/tmp/config.json", doc, flg, NULL, &err);if (err.code) {printf("写入错误(%u): %sn", err.code,错误消息); }// 释放 docyyjson_doc_free(idoc);yyjson_mut_doc_free(doc);
最新的(未发布的)文档可以在 doc 目录中访问。可以在此处查看发布版本的预生成 Doxygen HTML:
主页
构建和测试
API 和示例代码
数据结构
变更日志
将 yyjson 公开给其他语言或在内部使用 yyjson 来实现主要功能的项目的非详尽列表。如果您有一个使用 yyjson 的项目,请随时打开 PR 将其添加到此列表中。
项目 | 语言 | 描述 |
---|---|---|
py_yyjson | Python | yyjson 的 Python 绑定 |
或json | Python | 用于 Python 的 JSON 库,带有可选的 yyjson 后端 |
cpp-yyjson | C++ | 带有 yyjson 后端的 C++ JSON 库 |
反射cpp | C++ | 通过从结构中自动检索字段名称进行序列化的 C++ 库 |
yyjsonr | 右 | yyjson 的 R 绑定 |
阿南达 | 迅速 | 基于yyjson的JSON模型解码 |
鸭数据库 | C++ | DuckDB 是一个进程内 SQL OLAP 数据库管理系统 |
快速获取 | C | 一个类似 neofetch 的工具,用于获取系统信息并以漂亮的方式显示它们 |
兹律斯姆 | C | 使用 yyjson 序列化 JSON 项目文件的数字音频工作站 |
变得更加人性化 | C | 推荐引擎关注接收推荐者的独特性 |
mruby-yyjson | 姆鲁比 | 使用 yyjson 的 mruby 高效 JSON 解析和序列化库 |
YYJSON.jl | 朱莉娅 | yyjson 的 Julia 绑定 |
添加文档页面。
添加 CI 和 codecov 的 GitHub 工作流程。
添加更多测试:valgrind、sanitizer、fuzzing。
支持JSON Pointer查询和修改JSON。
为 JSON 读取器和写入器添加RAW
类型。
添加限制实数输出精度的选项。
添加支持 JSON5 的选项(如果可行)。
添加函数来比较两个 JSON 文档。
添加有关性能优化的文档。
确保ABI稳定性。
该项目是在 MIT 许可下发布的。