-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Open
Description
LJSON:全能、高性能、真流式的 C 语言 JSON 引擎和数值引擎
0 项目地址
LJSON 支持 Windows 和 Linux ,项目地址位于:
- github: https://github.com/lengjingzju/json
- gitee: https://gitee.com/lengjingzju/json
- 设计讨论: 关于JSON解析性能 lengjingzju/json#2
1. 项目定位与设计初衷
LJSON 诞生于 2019 年 10 月,比 yyjson 早一年,初衷并非单纯追求基准测试中的极限解析速度,而是要在 性能、内存占用、可编辑性、流式能力、可维护性 之间找到最佳平衡。
它目前状态是:
- 能在多数场景下媲美甚至超越 yyjson 的性能
- 提供 yyjson 架构无法小改实现的真流式处理能力
- 保持代码可读性和可扩展性,适合长期演进
2. 核心能力
双重核心
全能 JSON 处理
- 完整支持 JSON5 规范(十六进制、注释、尾逗号、单引号等)
- DOM / SAX 双解析模式
- 真流式文件(边读边解析,边写边打印)
高性能数值转换引擎
- 独创 ldouble 算法
- 浮点 ↔ 字符串转换性能远超标准库和主流算法(sprintf、grisu2、dragonbox)
- 精度是16位,在边界处理时追求最短而不是偶数(标准是16位或17位,取决于二进制指数转换为十进制指数的乘子的分辨率)
3. 架构与模式设计
LJSON 提供 7 种解析模式 与 4 种打印模式,覆盖从内存到文件、从 DOM 到 SAX 的全场景需求:
解析模式
- DOM 经典模式(malloc/free)
- DOM 内存池模式
- DOM 复用模式(可编辑,字符串原地复用)
- DOM 文件流模式(真流式)
- DOM 文件流内存池模式(真流式 + 内存池)
- SAX 模式(回调处理)
- SAX 文件流模式(真流式 + 回调)
打印模式
- DOM → 字符串
- DOM → 文件(真流式)
- SAX → 字符串
- SAX → 文件(真流式)
真流式:边读文件边解析,边打印边写文件,无需完整读入或生成中间大缓冲,内存占用可降至常数级,即使处理 1GB JSON 文件也仅需 KB 级内存。
yyjson ≈ LJSON 的 DOM 复用模式 + 激进只读优化
4. 与 yyjson 的设计差异
核心差异包括:
维度 | LJSON | yyjson |
---|---|---|
模式设计 | 多模式(含真流式、可编辑复用) | 单一复用模式(只读优化) |
可编辑性 | 复用模式可编辑 | 只读与可编辑严格分离(val / mut_val) |
字符串存储 | 标准 C 字符串(尾 1 个 \0 ) |
非标准尾 4 个 \0 (减少边界判断) |
对象存储 | key 与 value 一起存储 | key 与 value 分开存储 |
内存策略 | 按需分配,尽量避免浪费 | 大块预分配,冗余度高 |
访问加速 | json_items_t 缓存,数组 O(1)、对象 O(logN) |
未知是否有缓存,可能 O(N)/O(2N) |
优化手法 | 内联、分支预测、查表、缓存元信息;保持可读性 | 同类优化 + 大量宏循环展开,代码晦涩 |
流式处理 | 真流式解析/打印 | 不支持 |
5. 性能来源与权衡
优化技术对比
两者都使用:
- 内存池(块)优化
- 内联优化(inline)
- 分支预测优化(likely/unlikely)
- Cache 命中优化
- 查表优化
- 拷贝优化
- 信息记录优化(缓存字符串长度等)
差异:
- yyjson:大量宏进行循环手动展开,代码紧凑但晦涩,性能更激进;使用非标准特性(尾后 4 个
\0
、非对齐访问等)。 - LJSON:追求易维护、可扩展、低占用、高性能的工程化平衡。保持可读性,宏进行手动循环展开。
性能对比
yyjson 相当于只实现了 LJSON 的DOM复用模式,并且转换可编辑模式时对象和字符串都存储在内存块里,和LJSON的内存池原理一致。
- yyjson 只读复用模式 性能略高于 LJSON,来源于:
- 模式单一
- 激进资源使用(预分配冗余内存)
- 非标准特性(尾后 4 个
\0
、非对齐访问) - 宏循环展开
- yyjson 只读模式 性能和 LJSON 很接近,两者互有胜负
- yyjson 可编辑模式 性能可能大幅落后于 LJSON(大文件解析 yyjson 比 LJSON 内存占用多约一倍,速度慢约一倍)
注:如果 LJSON 放弃流式、标准字符串、可编辑性,采用更晦涩代码,可达到 yyjson 只读复用模式 性能,但那将不再是 LJSON 的设计哲学。
6. 优化机制亮点
- 零堆分配:首次分配后循环复用,避免频繁 malloc/free。
- 原地字符串复用:直接引用输入缓冲区,减少拷贝与内存带宽消耗。
- json_items 加速器:数组 O(1) 访问,对象 O(logN) 查找。
- 真流式管线:解析与 I/O 并行,消除峰值内存与额外拷贝。
- ldouble 数值引擎:浮点转字符串性能领先 sprintf 10~70 倍。
7. 多维度对比(可编辑模式)
对比维度 | LJSON | yyjson | RapidJSON | cJSON |
---|---|---|---|---|
解析性能 | 高(547ms,可编辑复用) | 中高(1011ms,可编辑) | 较高 | 中等 |
打印性能 | 高(真流式+ldouble) | 高(全缓冲) | 中等 | 低 |
内存占用 | 可常数级(流式) | 较高 | 较高 | 较高 |
CPU 特性依赖 | 低 | 低 | 中 | 低 |
可扩展性 | 高 | 低 | 中 | 高 |
代码可读性 | 高 | 极低 | 中 | 高 |
关键机制 | 零堆分配、内存池复用、原地字符串、json_items、ldouble | 原地复用、内存块、非标准字符串尾、循环展开 | 模板+分配器 | malloc/free |
8. 适用场景
- 大文件处理:GB 级 JSON 格式化/压缩,内存占用可常数级。
- 嵌入式系统:低内存、高性能需求。
- 高频读写:实时数据流解析与生成。
- 跨平台开发:Linux / Windows / 嵌入式 RTOS。
9. 设计哲学总结
yyjson:以极致性能为第一目标,通过激进优化手段和单一模式深耕,适合极限只读解析场景。
LJSON:追求易维护、可扩展、低占用、高性能的工程化平衡,适合通用、可编辑、流式处理、大文件低内存占用的场景。纯 C 实现,零第三方依赖,跨平台编译,接口设计参考 cJSON,逻辑清晰,编译速度快,易于二次开发。
LJSON 的价值不仅在于跑分,更在于它能在真实工程环境中,以极低的内存占用和高性能,稳定支撑多样化的 JSON 处理需求。
Metadata
Metadata
Assignees
Labels
No labels