1、介紹
RyanJson是一個(gè)小巧的c語(yǔ)言json解析器,包含json文本文件解析 / 生成,專(zhuān)門(mén)針對(duì)內(nèi)存占用進(jìn)行優(yōu)化,相比cJSON內(nèi)存占用減少30% - 60%,運(yùn)行速度和cJSON差不多。
低內(nèi)存占用:使用動(dòng)態(tài)擴(kuò)展技術(shù),在32位系統(tǒng)下,一個(gè)基礎(chǔ)json節(jié)點(diǎn)僅占用8字節(jié)。
開(kāi)發(fā)人員友好:僅有一個(gè)c文件和頭文件輕松集成,hook函數(shù)方便自定義內(nèi)存鉤子。類(lèi)cJSON的api,遷移成本低。
嚴(yán)格但不嚴(yán)苛:符合 RFC 8295 大部分JSON標(biāo)準(zhǔn),支持無(wú)限的json嵌套級(jí)別(需注意堆??臻g)、靈活的配置修改項(xiàng)
可擴(kuò)展性:允許注釋(需調(diào)用mini函數(shù)清除注釋后再解析)、尾隨逗號(hào)等無(wú)效字符(parse時(shí)可配置是否允許)等
2、設(shè)計(jì)
RyanJson設(shè)計(jì)時(shí)大量借鑒了 json 和 cJSON ! 是從 json 的基礎(chǔ)上修改來(lái)的
json語(yǔ)法是JavaScript對(duì)象語(yǔ)法的子集
在json語(yǔ)法中,數(shù)據(jù)以鍵值對(duì)的形式存儲(chǔ)(數(shù)組沒(méi)有key)
在RyanJson解析器中,使用結(jié)構(gòu)體來(lái)表示一個(gè)鍵值對(duì),是存儲(chǔ)的最小單元,結(jié)構(gòu)如下:
struct RyanJsonNode
{
uint32_t info; // 包含類(lèi)型,key等標(biāo)志
struct RyanJsonNode *next; // 單鏈表node節(jié)點(diǎn)
// [char key] 有key的json節(jié)點(diǎn), 會(huì)動(dòng)態(tài)創(chuàng)建指針
// 有value值的節(jié)點(diǎn), 會(huì)動(dòng)態(tài)創(chuàng)建指針
// [int32_t value / double value / char value / RyanJson_t item]
};
typedef struct RyanJsonNode *RyanJson_t;
此結(jié)構(gòu)體包含兩個(gè)固定成員 info 和 next;
info:為當(dāng)前節(jié)點(diǎn)的配置信息用來(lái)表示 節(jié)點(diǎn)數(shù)據(jù)類(lèi)型 和 flag標(biāo)志位。
bits low --> high
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | NA | NA | .......
______________________________/ | | |
low 8bits | | |
| | | |
V | | |
RyanJsonTypeUnknow (bit0) | | |
RyanJsonTypeNull (bit1) | | |
RyanJsonTypeBool (bit2) | | +----> RyanJsonWithKeyFlag (1 << 10)
RyanJsonTypeNumber (bit3) | |
RyanJsonTypeString (bit4) | +--------> RyanJsonValueNumberIntFlag (1 << 9)
RyanJsonTypeArray (bit5) |
RyanJsonTypeObject (bit6) +------------> RyanJsonValueBoolTrueFlag (1 << 8)
spare (bit7)
next:指針指向鏈表下一個(gè)節(jié)點(diǎn)
{
"name": "RyanJson",
next (
"version": "xxx",
next (
"repository": "https://github.com/Ryan-CW-Code/RyanJson",
next (
"keywords": ["json", "streamlined", "parser"],
next ( _ item _/ _ next _/ _ next _/
"others": {
...
}
}
此結(jié)構(gòu)體還包括兩個(gè)可能動(dòng)態(tài)創(chuàng)建的成員 key 和 value;
key:存儲(chǔ)鍵值對(duì)的 key 信息,當(dāng)存在key時(shí)會(huì)在申請(qǐng)RyanJsonNode內(nèi)存時(shí),動(dòng)態(tài)添加。
value:存儲(chǔ)鍵值對(duì)的 value 信息,會(huì)根據(jù)不同節(jié)點(diǎn)類(lèi)型創(chuàng)建不同的value值。會(huì)在申請(qǐng)RyanJsonNode內(nèi)存時(shí),動(dòng)態(tài)添加。
3、測(cè)試
測(cè)試代碼可在本項(xiàng)目根目錄查看。
性能測(cè)試
RyanDocs文檔中心,有基于 yyjson_benchmark 的測(cè)試結(jié)果
內(nèi)存占用測(cè)試
RFC 8295 標(biāo)準(zhǔn)測(cè)試,大部分嵌入式場(chǎng)景不會(huì)出現(xiàn)復(fù)雜的特殊json結(jié)構(gòu)
RyanJson和cJSON都不適合處理復(fù)雜的UTF-16字符集,如果項(xiàng)目需要兼容Unicode字符集,可以考慮yyjson / json-c
4、局限性
使用int / double表示json中的number類(lèi)型,精度有所丟失。建議64位的number類(lèi)型最好用string字符串表示。
對(duì)象中允許有重復(fù)的key,RyanJson庫(kù)采用單向鏈表,會(huì)訪問(wèn)到第一個(gè)對(duì)象。
-
存儲(chǔ)器
+關(guān)注
關(guān)注
39文章
7692瀏覽量
170008 -
C語(yǔ)言
+關(guān)注
關(guān)注
183文章
7634瀏覽量
143901 -
RFC
+關(guān)注
關(guān)注
0文章
16瀏覽量
10265 -
JSON
+關(guān)注
關(guān)注
0文章
122瀏覽量
7636
發(fā)布評(píng)論請(qǐng)先 登錄
mesh的內(nèi)存占用能否優(yōu)化?
stm32 使用u*** host庫(kù)占用內(nèi)存空間很大?。?!
減少Q(mào)Q內(nèi)存占用的一則方法
Android高效內(nèi)存:讓圖片占用盡可能少的內(nèi)存
Java服務(wù)器內(nèi)存和CPU占用過(guò)高的原因
電腦內(nèi)存占用過(guò)高加內(nèi)存條起作用嗎
面向NoSQL數(shù)據(jù)庫(kù)的JSON文檔異常檢測(cè)模型

自編適用于嵌入式單片機(jī)Json封包與解析的程序

Windows不明內(nèi)存占用案例分析:Driver Locked

如何利用Python和pandas來(lái)處理json數(shù)據(jù)

什么是JSON數(shù)據(jù)庫(kù)

關(guān)于JSON數(shù)據(jù)庫(kù)

評(píng)論