Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bec5345
refactor: 避免未对齐访问
Ryan-CW-Code Dec 25, 2025
c8d8140
refactor: 手动实现访问非对其指针
Ryan-CW-Code Dec 25, 2025
9c9d896
refactor: 优化json存储结构
Ryan-CW-Code Jan 6, 2026
aa5fb75
refactor: 优化函数命名
Ryan-CW-Code Jan 6, 2026
9111db2
fix: inline模式chang修复并补充测试例程
Ryan-CW-Code Jan 6, 2026
4d15c73
feat: 兼容大端环境
Ryan-CW-Code Jan 6, 2026
40e7db5
test: 补充更多示例
Ryan-CW-Code Jan 6, 2026
938076d
test: 补充测试描述
Ryan-CW-Code Jan 6, 2026
e7a1efd
doc: 完善readme
Ryan-CW-Code Jan 6, 2026
0b97df2
refactor: 完善模糊测试覆盖率
Ryan-CW-Code Jan 6, 2026
14b3f07
refactor: 优化print double的实现
Ryan-CW-Code Jan 7, 2026
1141052
style: 整理目录
Ryan-CW-Code Jan 7, 2026
c02b973
test: 优化测试代码
Ryan-CW-Code Jan 7, 2026
a0c0742
refactor: RyanJsonCompareDouble 开放出来
Ryan-CW-Code Jan 7, 2026
3db45e2
refactor: 优化double打印实现
Ryan-CW-Code Jan 7, 2026
93dbbdd
test: 完善jsonUtils模糊测试覆盖率
Ryan-CW-Code Jan 7, 2026
92a59cf
test: 增加数据解析一致性测试,优化测试代码
Ryan-CW-Code Jan 7, 2026
65dff5d
refactor: 优化double打印
Ryan-CW-Code Jan 8, 2026
94cbf58
refactor: 撤回double解析共用的函数
Ryan-CW-Code Jan 8, 2026
83b338e
test: 优化测试代码
Ryan-CW-Code Jan 8, 2026
06ea8f8
refactor: 再次整合double的解析和打印
Ryan-CW-Code Jan 8, 2026
5a68fc1
refactor: 优化嵌入式平台打印Double
Ryan-CW-Code Jan 8, 2026
0cb3edc
doc: 更新readme
Ryan-CW-Code Jan 8, 2026
b8b98ca
refactor: 优化double打印实现
Ryan-CW-Code Jan 11, 2026
10593b6
test: 拆分fuzzer测试文件,更新字典
Ryan-CW-Code Jan 11, 2026
cbda13f
test: 优化部分测试代码
Ryan-CW-Code Jan 12, 2026
b63328e
doc: 更新readme
Ryan-CW-Code Jan 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@
# Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-const-correctness,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-misc-no-recursion,-misc-use-anonymous-namespace,readability-identifier-naming,-misc-include-cleaner'

Checks:
- "-*,clang-diagnostic-*,clang-analyzer-*,llvm-*,concurrency-*,performance-*,cert-*"
- "-*,clang-diagnostic-*,clang-analyzer-*,concurrency-*,performance-*,cert-*"
# 静默的窄化转换交给编译器来判断?
- 'llvm-*,-llvm-include-order'
- 'bugprone-*,-bugprone-easily-swappable-parameters'
- 'readability-identifier-naming'
- 'misc-*,-misc-const-correctness,-misc-no-recursion,-misc-include-cleaner'
Expand Down
10 changes: 10 additions & 0 deletions .clangd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Index:
Background: Build # 开启后台索引

# 如果你的 compile_commands.json 不在根目录,需要在这里显式指定
CompileFlags:
CompilationDatabase: ".vscode"
Comment on lines +1 to +6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check if .clangd file exists and read its content
if [ -f ".clangd" ]; then
  echo "=== .clangd file content ==="
  cat -n .clangd
else
  echo ".clangd file not found"
fi

Repository: Ryan-CW-Code/RyanJson

Length of output: 409


🏁 Script executed:

# Search for compile_commands.json in common locations
echo "=== Searching for compile_commands.json ==="
find . -name "compile_commands.json" -type f 2>/dev/null | head -20

Repository: Ryan-CW-Code/RyanJson

Length of output: 108


🏁 Script executed:

# Check if .vscode directory exists and list its contents
if [ -d ".vscode" ]; then
  echo "=== .vscode directory contents ==="
  ls -la .vscode/ 2>/dev/null | head -20
else
  echo ".vscode directory does not exist"
fi

Repository: Ryan-CW-Code/RyanJson

Length of output: 273


compile_commands.json 文件缺失。

CompilationDatabase 配置指向 ".vscode" 目录,但 compile_commands.json 在该目录(以及根目录)中都不存在。clangd 无法找到编译数据库,将无法正确索引和分析代码。需要生成 compile_commands.json 文件或将配置路径指向正确位置。

🤖 Prompt for AI Agents
In @.clangd around lines 1-6, The .clangd config points CompilationDatabase to
".vscode" but compile_commands.json is missing; fix by either generating a
compilation database (e.g., enable CMake's CMAKE_EXPORT_COMPILE_COMMANDS or run
bear/scan-build to create compile_commands.json) and placing it in the ".vscode"
directory, or update the CompilationDatabase field in .clangd to the actual
directory containing the generated compile_commands.json (or remove the explicit
setting to use the project root). Ensure the file is named exactly
compile_commands.json so clangd can discover it.


Diagnostics:
UnusedIncludes: None # 关键:这会关闭“未使用头文件”的提示
MissingIncludes: None # 可选:关闭“缺失头文件”的提示
79 changes: 31 additions & 48 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
{
"clangd.enable": false,
"C_Cpp.intelliSenseEngine": "default",
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"c-cpp-flylint.enable": true,
"Lua.codeLens.enable": false,
"Lua.hint.enable": false,
"Lua.completion.enable": false,
"Lua.format.enable": false,
"Lua.hover.enable": false,
"Lua.diagnostics.enable": false,
"Lua.semantic.enable": false,
"Lua.addonManager.enable": false,
"Lua.signatureHelp.enable": false,
"clangd.enable": true,
"clangd.arguments": [
],
"C_Cpp.intelliSenseEngine": "disabled",
"C_Cpp.errorSquiggles": "disabled", // 关闭微软的波浪线
"C_Cpp.autocomplete": "disabled", // 关闭微软的自动补全
"C_Cpp.default.compileCommands": "${workspaceFolder}/.vscode/compile_commands.json",
"C_Cpp.codeAnalysis.clangTidy.enabled": false,
"C_Cpp.codeAnalysis.clangTidy.args": [
// "--extra-arg=-ferror-limit=1"
// "--extra-arg=-m32",
"--extra-arg=--target=arm-none-eabi-gcc"
],
Comment on lines +23 to +27
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

目标三元组格式可能不正确。

--target=arm-none-eabi-gcc 中的 -gcc 后缀是编译器可执行文件名的一部分,不是目标架构的组成部分。正确的目标三元组应该是 arm-none-eabi

🔧 建议修复
     "C_Cpp.codeAnalysis.clangTidy.args": [
         // "--extra-arg=-ferror-limit=1"
         // "--extra-arg=-m32",
-        "--extra-arg=--target=arm-none-eabi-gcc"
+        "--extra-arg=--target=arm-none-eabi"
     ],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"C_Cpp.codeAnalysis.clangTidy.args": [
// "--extra-arg=-ferror-limit=1"
// "--extra-arg=-m32",
"--extra-arg=--target=arm-none-eabi-gcc"
],
"C_Cpp.codeAnalysis.clangTidy.args": [
// "--extra-arg=-ferror-limit=1"
// "--extra-arg=-m32",
"--extra-arg=--target=arm-none-eabi"
],
🤖 Prompt for AI Agents
In @.vscode/settings.json around lines 23 - 27, The value in
C_Cpp.codeAnalysis.clangTidy.args uses an incorrect target triple; replace the
string "--extra-arg=--target=arm-none-eabi-gcc" with
"--extra-arg=--target=arm-none-eabi" so the target triple is correct (remove the
"-gcc" compiler suffix) in the array assigned to
"C_Cpp.codeAnalysis.clangTidy.args".

"c-cpp-flylint.enable": false,
"c-cpp-flylint.cppcheck.severityLevels": {
"error": "Error",
"warning": "Warning",
Expand All @@ -12,49 +31,13 @@
"information": "Information"
},
"c-cpp-flylint.cppcheck.extraArgs": [
// "--suppress=constParameterPointer",
// "--suppress=constParameterCallback",
"--suppress=constParameterPointer",
"--suppress=constParameterCallback",
"--check-level=exhaustive",
// "--suppress=variableScope",
// "--suppress=unreadVariable",
// "--suppress=constVariablePointer",
// "--suppress=constParameter",
],
"files.watcherExclude": {
"**/test/fuzzer/corpus/**": true,
"./docs": true,
"./build": true,
"./.xmake": true,
},
"files.exclude": {
"**/test/fuzzer/corpus/**": true,
"./docs": true,
"./build": true,
"./.xmake": true,
},
"files.associations": {
"*.c": "c",
"inttypes.h": "c",
"float.h": "c",
"stdlib.h": "c",
"limits.h": "c",
"stdio.h": "c",
"stdint.h": "c",
"ryanjsontest.h": "c",
"dirent.h": "c",
"valloc.h": "c",
"initializer_list": "c",
"array": "c",
"string_view": "c",
"utility": "c",
"math.h": "c",
"compare": "c",
"type_traits": "c",
"cjson.h": "c",
"ryanjson.h": "c",
"string.h": "c",
"stdarg.h": "c",
"cstdlib": "c",
"ryanjsonconfig.h": "c"
},
"--suppress=variableScope",
"--suppress=unreadVariable",
"--suppress=constVariablePointer",
"--suppress=constParameter",
"--suppress=unusedStructMember",
]
}
179 changes: 108 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

### 2、设计

**RyanJson设计时大量借鉴了 [json](https://api.gitee.com/Lamdonn/json) 和 [cJSON](https://github.com/DaveGamble/cJSON) ! **
**RyanJson设计时借鉴了 [json](https://api.gitee.com/Lamdonn/json) 和 [cJSON](https://github.com/DaveGamble/cJSON) ! **

Json语法是**JavaScript**对象语法的子集,可通过下面两个连接学习json语法。

Expand All @@ -46,13 +46,20 @@ struct RyanJsonNode
{
struct RyanJsonNode *next; // 单链表节点指针

/*
* 在 next 后紧跟一个字节的 flag,用于描述节点的核心信息:
/**
* @brief RyanJson 节点结构体
* 每个节点由链表连接,包含元数据标识 (Flag) 与动态载荷存储区。
*
* 位分布如下:
* 内存布局:
* [ next指针 | flag(1字节) | padding/指针空间 | 动态载荷区 ]
*
* @brief 节点元数据标识 (Flag)
* 紧跟 next 指针后,利用 1 字节位域描述节点类型及存储状态。
*
* flag 位分布定义:
* bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
* -----------------------------------------------------
* 保留 KeyLen KeyLen HasKey NumExt Type2 Type1 Type0
* strMode KeyLen KeyLen HasKey NumExt Type2 Type1 Type0
*
* 各位含义:
* - bit0-2 : 节点类型
Expand All @@ -61,58 +68,88 @@ struct RyanJsonNode
*
* - bit3 : 扩展位
* Bool 类型:0=false, 1=true
* Number 类型:0=int, 1=double
* Number 类型:0=int(4字节), 1=double(8字节)
*
* - bit4 : 是否包含 Key
* 0=无 Key(数组元素)
* 1=有 Key(对象成员)
*
* - bit5-6 : Key 长度字段字节数
* 00=1字节 (≤255)
* 01=2字节 (≤65535)
* 10=3字节 (≤16M)
* 00=1字节 (≤UINT8_MAX)
* 01=2字节 (≤UINT16_MAX)
* 10=3字节 (≤UINT24_MAX)
* 11=4字节 (≤UINT32_MAX)
*
* - bit7 : 保留位(未来可用于压缩标记、特殊类型等)
*/

/*
* flag 后若节点包含 key / strValue,则跟随一个指针,
* 指向存储区:[ keyLen | key | stringValue ]
* 其中 keyLen 的大小由 flag 中的长度信息决定(最多 4 字节)。
*
* 在指针之后,根据节点类型存储具体数据:
* - null / bool : 由 flag 表示
* - string : 由上述指针指向
* - number : 根据 flag 决定存储 int(4字节) 或 double(8字节)
* - object : 动态分配空间存储子节点,链表结构如下:
*
* {
* "name": "RyanJson",
* next (
* "version": "xxx",
* next (
* "repository": "https://github.com/Ryan-CW-Code/RyanJson",
* next (
* "keywords": ["json", "streamlined", "parser"],
* next (
* "others": { ... }
* )))
* }
*/

/*
* 设计特点:
* - 一个 Json 节点最多 malloc 两次(一次节点本身,一次可选的 key/stringValue),
* 对嵌入式系统非常友好,减少 malloc 头部开销, 尽可能的减少内存碎片。
* - bit7 : 表示key / strValue 存储模式
* 1:inline 模式, 0=ptr 模式

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

文档描述有误。根据 RyanJson.c 中的实现,当 strIsPtr 标志位为 RyanJsonTrue (1) 时,表示使用的是指针模式(ptr 模式);为 RyanJsonFalse (0) 时,表示使用的是内联模式(inline 模式)。

当前的文档描述 1:inline 模式, 0=ptr 模式 与实现正好相反,容易误导开发者。请修正此处的描述。

Suggested change
* - bit7 : 表示key / strValue 存储模式
* 1:inline 模式, 0=ptr 模式
* - bit7 : 表示key / strValue 存储模式
* 0:inline 模式, 1=ptr 模式

*
* - key 和 stringValue 必须通过指针管理:
* * 如果直接放在节点里,虽然只需一次 malloc,
* 但修改场景会遇到替换/释放困难。
* * 用户可能传递的 Json 对象不是指针,无法直接替换节点,
* 要求应用层传递指针会增加侵入性,不符合“应用层无需修改”的目标。
* @brief 动态载荷存储区
* 目的:
* - 在保持 API 易用性和稳定性的同时,最大限度减少 malloc 调用次数。
* - 尤其在嵌入式平台,malloc 代价高昂:不仅有堆头部空间浪费,还会产生内存碎片。
* - 通过利用结构体内的对齐填充 (Padding) 和指针空间,形成一个灵活的缓冲区。
*
* 存储策略:
* 利用结构体内存对齐产生的 Padding(如 Flag 后的空隙)以及原本用于存储指针的空间,形成一个缓冲区
* 若节点包含 key / strValue,则可能有两种方案:
* 1. inline 模式 (小数据优化)
* - 当 (KeyLen + Key + Value) 的总长度 ≤ 阈值时,直接存储在结构体内部。
* - 阈值计算公式:
* 阈值 = Padding + sizeof(void*) + (malloc头部空间的一半),再向上对齐到字节边界。
* 举例:
* - 内存对齐:4字节
* - malloc头部空间:8字节
* - 可用空间 = 3 (flag后padding) + 4 (指针空间) + 4 (malloc头部一半)
* - 向上对齐后得到阈值12字节
* - 存储布局:
* [ KeyLen | Key | Value ]
* 起始地址即为 flag 之后,数据紧凑排列,无需额外 malloc。
*
* 2. ptr 模式 (大数据)
* - 当数据长度 > 阈值时,结构体存储一个指针,指向独立的堆区。
* - 存储布局:
* [ KeyLen | *ptr ] -> (ptr指向) [ Key | Value ]
* - KeyLen 的大小由 flag 中的长度字段决定 (最多 4 字节)。
* - 这样保证大数据不会撑爆结构体,同时保持 API 一致性。

* 其他类型的存储:
* - null / bool : 由 flag 位直接表示,无需额外空间。
* - number : 根据 flag 扩展位决定存储 int(4字节) 或 double(8字节)。
* - object : 动态分配空间存储子节点,采用链表结构。
*
* 设计考量:
* - malloc 在嵌入式平台的开销:
* * RTT 最小内存管理算法中,malloc 头部约 12 字节(可以考虑tlsf算法头部空间仅4字节,内存碎片也控制的很好,适合物联网应用)。
* * 一个 RyanJson 节点本身可能只有个位数字节,头部空间就让内存占用翻倍。
* - 因此:
* * 小数据尽量 inline 存储,避免二次 malloc。
* * 大数据 fallback 到 ptr 模式,保证灵活性。
* - 修改场景:
* * 理想情况:节点结构体后面直接跟 key/strValue,修改时释放并重新申请节点。
* * 但这样 changKey/changStrValue 接口改动太大,用户层需要修改指针,代价高。
* * 实际策略:提供就地修改接口。
* - 若新值长度 ≤ 原有 inline 缓冲区,直接覆盖。
* - 若超过阈值,自动切换到 ptr 模式,用户层无需关心。
*
* - 因此采用指针方式,保证灵活性和低侵入性。
* 链表结构示例:
* {
* "name": "RyanJson",
* next (
* "version": "xxx",
* next (
* "repository": "https://github.com/Ryan-CW-Code/RyanJson",
* next (
* "keywords": [
* "json",
* next (
* "streamlined",
* next (
* "parser"
* ))
* ],
* next (
* "others": { ... }
* }
*/
};

Expand Down Expand Up @@ -188,60 +225,60 @@ typedef struct RyanJsonNode *RyanJson_t;


#### 内存占用测试
*(20251222 linux平台,**不考虑malloc头部空间)**测试代码可在本项目根目录`RyanJsonExample`文件夹查看。新版本内存占用更低!*
(20251222 **malloc头部空间8字节,内存对齐4字节**)测试代码可在本项目根目录`RyanJsonExample`文件夹查看。

```
*****************************************************************************
*************************** RyanJson / cJSON / yyjson 内存对比程序 **************************
*****************************************************************************

--------------------------- 混合类型json数据测试 --------------------------
json原始文本长度为 2265, 序列化后RyanJson内存占用: 3613, cJSON内存占用: 9160, yyjson内存占用: 8692
比cJSON节省: 60.56% 内存占用, 比yyjson节省: 58.43% 内存占用
json原始文本长度为 2265, 序列化后RyanJson内存占用: 4912, cJSON内存占用: 11336, yyjson内存占用: 8784
比cJSON节省: 56.67% 内存占用, 比yyjson节省: 44.08% 内存占用

--------------------------- 对象占多json数据测试 --------------------------
json原始文本长度为 3991, 序列化后RyanJson内存占用: 5436, cJSON内存占用: 11633, yyjson内存占用: 12640
比cJSON节省: 53.27% 内存占用, 比yyjson节省: 56.99% 内存占用
--------------------------- 全是对象json数据测试 --------------------------
json原始文本长度为 3991, 序列化后RyanJson内存占用: 7944, cJSON内存占用: 16020, yyjson内存占用: 12884
比cJSON节省: 50.41% 内存占用, 比yyjson节省: 38.34% 内存占用

--------------------------- 数组占多json数据测试 --------------------------
json原始文本长度为 1205, 序列化后RyanJson内存占用: 2365, cJSON内存占用: 7340, yyjson内存占用: 5028
比cJSON节省: 67.78% 内存占用, 比yyjson节省: 52.96% 内存占用
json原始文本长度为 1205, 序列化后RyanJson内存占用: 3696, cJSON内存占用: 8680, yyjson内存占用: 5068
比cJSON节省: 57.42% 内存占用, 比yyjson节省: 27.07% 内存占用

--------------------------- 小对象json 混合类型内存占用测试 --------------------------
json原始文本长度为 90, 序列化后RyanJson内存占用: 131, cJSON内存占用: 309, yyjson内存占用: 636
比cJSON节省: 57.61% 内存占用, 比yyjson节省: 79.40% 内存占用
json原始文本长度为 90, 序列化后RyanJson内存占用: 168, cJSON内存占用: 392, yyjson内存占用: 648
比cJSON节省: 57.14% 内存占用, 比yyjson节省: 74.07% 内存占用

--------------------------- 小对象json 纯字符串内存占用测试 --------------------------
json原始文本长度为 100, 序列化后RyanJson内存占用: 144, cJSON内存占用: 339, yyjson内存占用: 636
比cJSON节省: 57.52% 内存占用, 比yyjson节省: 77.36% 内存占用
json原始文本长度为 100, 序列化后RyanJson内存占用: 216, cJSON内存占用: 472, yyjson内存占用: 648
比cJSON节省: 54.24% 内存占用, 比yyjson节省: 66.67% 内存占用
```

RT-Thread平台考虑malloc**头部空间12字节**情况下,嵌入式平台下占用最高的反而是malloc的内存头开销,所以建议用户优先选择malloc头部空间小的heap管理算法
RT-Thread平台 **malloc头部空间12字节,内存对齐8字节**测试代码可在本项目根目录`RyanJsonExample`文件夹查看

```
*****************************************************************************
*************************** RyanJson / cJSON / yyjson 内存对比程序 **************************
*****************************************************************************

--------------------------- 混合类型json数据测试 --------------------------
json原始文本长度为 2265, 序列化后RyanJson内存占用: 7993, cJSON内存占用: 13732, yyjson内存占用: 8752
比cJSON节省: 41.79% 内存占用, 比yyjson节省: 8.67% 内存占用
json原始文本长度为 2265, 序列化后RyanJson内存占用: 5056, cJSON内存占用: 11336, yyjson内存占用: 8784
比cJSON节省: 55.40% 内存占用, 比yyjson节省: 42.44% 内存占用

--------------------------- 对象占多json数据测试 --------------------------
json原始文本长度为 3991, 序列化后RyanJson内存占用: 10668, cJSON内存占用: 19109, yyjson内存占用: 12712
比cJSON节省: 44.17% 内存占用, 比yyjson节省: 16.08% 内存占用
--------------------------- 全是对象json数据测试 --------------------------
json原始文本长度为 3991, 序列化后RyanJson内存占用: 7832, cJSON内存占用: 16020, yyjson内存占用: 12884
比cJSON节省: 51.11% 内存占用, 比yyjson节省: 39.21% 内存占用

--------------------------- 数组占多json数据测试 --------------------------
json原始文本长度为 1205, 序列化后RyanJson内存占用: 5449, cJSON内存占用: 10424, yyjson内存占用: 5076
比cJSON节省: 47.73% 内存占用, 比yyjson节省: -7.35% 内存占用
json原始文本长度为 1205, 序列化后RyanJson内存占用: 3840, cJSON内存占用: 8680, yyjson内存占用: 5068
比cJSON节省: 55.76% 内存占用, 比yyjson节省: 24.23% 内存占用

--------------------------- 小对象json 混合类型内存占用测试 --------------------------
json原始文本长度为 90, 序列化后RyanJson内存占用: 287, cJSON内存占用: 477, yyjson内存占用: 672
比cJSON节省: 39.83% 内存占用, 比yyjson节省: 57.29% 内存占用
json原始文本长度为 90, 序列化后RyanJson内存占用: 172, cJSON内存占用: 392, yyjson内存占用: 648
比cJSON节省: 56.12% 内存占用, 比yyjson节省: 73.46% 内存占用

--------------------------- 小对象json 纯字符串内存占用测试 --------------------------
json原始文本长度为 100, 序列化后RyanJson内存占用: 300, cJSON内存占用: 567, yyjson内存占用: 672
比cJSON节省: 47.09% 内存占用, 比yyjson节省: 55.36% 内存占用
json原始文本长度为 100, 序列化后RyanJson内存占用: 180, cJSON内存占用: 472, yyjson内存占用: 648
比cJSON节省: 61.86% 内存占用, 比yyjson节省: 72.22% 内存占用
```


Expand Down
Loading