0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

更低內(nèi)存占用的通用Json庫-RyanJson

冬至子 ? 來源:Ryan_CW ? 作者:Ryan_CW ? 2023-08-24 17:23 ? 次閱讀

1、介紹

RyanJson是一個(gè)小巧的c語言json解析器,包含json文本文件解析 / 生成,專門針對(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é)。
開發(fā)人員友好:僅有一個(gè)c文件和頭文件輕松集成,hook函數(shù)方便自定義內(nèi)存鉤子。類cJSON的api,遷移成本低。
嚴(yán)格但不嚴(yán)苛:符合 RFC 8295 大部分JSON標(biāo)準(zhǔn),支持無限的json嵌套級(jí)別(需注意堆棧空間)、靈活的配置修改項(xiàng)
可擴(kuò)展性:允許注釋(需調(diào)用mini函數(shù)清除注釋后再解析)、尾隨逗號(hào)等無效字符(parse時(shí)可配置是否允許)等

2、設(shè)計(jì)
RyanJson設(shè)計(jì)時(shí)大量借鑒了 json 和 cJSON ! 是從 json 的基礎(chǔ)上修改來的

json語法是JavaScript對(duì)象語法的子集

在json語法中,數(shù)據(jù)以鍵值對(duì)的形式存儲(chǔ)(數(shù)組沒有key)

在RyanJson解析器中,使用結(jié)構(gòu)體來表示一個(gè)鍵值對(duì),是存儲(chǔ)的最小單元,結(jié)構(gòu)如下:

struct RyanJsonNode
{
uint32_t info; // 包含類型,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)的配置信息用來表示 節(jié)點(diǎn)數(shù)據(jù)類型 和 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)類型創(chuàng)建不同的value值。會(huì)在申請(qǐng)RyanJsonNode內(nèi)存時(shí),動(dòng)態(tài)添加。

3、測試
測試代碼可在本項(xiàng)目根目錄查看。

性能測試
RyanDocs文檔中心,有基于 yyjson_benchmark 的測試結(jié)果

內(nèi)存占用測試

1.jpg

RFC 8295 標(biāo)準(zhǔn)測試,大部分嵌入式場景不會(huì)出現(xiàn)復(fù)雜的特殊json結(jié)構(gòu)
RyanJson和cJSON都不適合處理復(fù)雜的UTF-16字符集,如果項(xiàng)目需要兼容Unicode字符集,可以考慮yyjson / json-c

1.jpg

4、局限性
使用int / double表示json中的number類型,精度有所丟失。建議64位的number類型最好用string字符串表示。
對(duì)象中允許有重復(fù)的key,RyanJson庫采用單向鏈表,會(huì)訪問到第一個(gè)對(duì)象。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲(chǔ)器
    +關(guān)注

    關(guān)注

    38

    文章

    7366

    瀏覽量

    163092
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134086
  • RFC
    RFC
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    10084
  • JSON
    +關(guān)注

    關(guān)注

    0

    文章

    113

    瀏覽量

    6899
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    mesh的內(nèi)存占用能否優(yōu)化?

    我測試到esp_mesh在開啟的情況下,即打開wifi和打開mesh,DRAM會(huì)占用大約130kb內(nèi)存。且測試發(fā)現(xiàn)esp32剩余內(nèi)存不足大約60kb的時(shí)候系統(tǒng)會(huì)重啟。這樣來說300KB內(nèi)存
    發(fā)表于 06-28 15:32

    stm32 使用u*** host占用內(nèi)存空間很大?。?!

    如何解決stm32 使用u*** host占用內(nèi)存空間很大的問題呢???
    發(fā)表于 01-22 16:44

    枚舉變量占用多少內(nèi)存?

    枚舉變量占用多少內(nèi)存
    發(fā)表于 10-11 08:07

    請(qǐng)問STM32可以用JSON嗎?

    STM32能不能支持JSON的操作
    發(fā)表于 10-23 07:45

    減少Q(mào)Q內(nèi)存占用的一則方法

    減少Q(mào)Q內(nèi)存占用的一則方法 隨著QQ的功能越來越多,QQ占用的資源也是越來越多,為了減小它的資源占用量,大家想出了多種方法其中有把
    發(fā)表于 01-14 11:23 ?679次閱讀

    Android高效內(nèi)存:讓圖片占用盡可能少的內(nèi)存

    在做內(nèi)存優(yōu)化的時(shí)候,我們發(fā)現(xiàn)除了解決內(nèi)存泄露問題,剩下的就只有想辦法減少真實(shí)的內(nèi)存占用。而在App中,大部分內(nèi)存可能被我們圖片
    的頭像 發(fā)表于 06-02 11:05 ?4848次閱讀

    Java服務(wù)器內(nèi)存和CPU占用過高的原因

    造成服務(wù)器內(nèi)存占用過高只有兩種情況:內(nèi)存溢出或內(nèi)存泄漏
    的頭像 發(fā)表于 03-21 15:50 ?2.2w次閱讀

    電腦內(nèi)存占用過高加內(nèi)存條起作用嗎

    電腦內(nèi)存占用過高加內(nèi)存條有用。內(nèi)存容量小是內(nèi)容占用過高的其中一個(gè)原因,所以加內(nèi)存條可以解決問題;
    發(fā)表于 06-16 10:25 ?6408次閱讀

    虛擬機(jī):查看進(jìn)程內(nèi)存和CPU占用的方法

    虛擬機(jī):查看進(jìn)程內(nèi)存和CPU占用的方法
    的頭像 發(fā)表于 06-22 11:06 ?8268次閱讀

    Linux:測試進(jìn)程占用的虛擬內(nèi)存大小

    Linux:測試進(jìn)程占用的虛擬內(nèi)存大小
    的頭像 發(fā)表于 06-23 09:23 ?2772次閱讀
    Linux:測試進(jìn)程<b class='flag-5'>占用</b>的虛擬<b class='flag-5'>內(nèi)存</b>大小

    面向NoSQL數(shù)據(jù)JSON文檔異常檢測模型

    數(shù)據(jù)常用的數(shù)據(jù)存儲(chǔ)格式,JSON因簡單性和靈活性備受歡迎。然而,NoSαL數(shù)據(jù)缺乏模弌信息,在JSON文檔存入數(shù)據(jù)辶前,需要對(duì)其進(jìn)行數(shù)
    發(fā)表于 04-13 15:30 ?20次下載
    面向NoSQL數(shù)據(jù)<b class='flag-5'>庫</b>的<b class='flag-5'>JSON</b>文檔異常檢測模型

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

    @[TOC]**自編適用于嵌入式單片機(jī)Json封包與解析的程序**說明:由于網(wǎng)上提供的標(biāo)準(zhǔn)JSON,對(duì)向單片機(jī)這類的小設(shè)備占用資源過多,很不實(shí)際,所以用C語言自編,在平臺(tái)STM32F
    發(fā)表于 12-05 16:51 ?17次下載
    自編適用于嵌入式單片機(jī)<b class='flag-5'>Json</b>封包與解析的程序

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

    前一段有客戶反映Windows系統(tǒng)下不明內(nèi)存占用越來越多,128GB物理內(nèi)存的主機(jī),啟動(dòng)完成后就有大約一半的內(nèi)存占用,導(dǎo)致留給應(yīng)用的
    的頭像 發(fā)表于 09-25 14:49 ?1439次閱讀
    Windows不明<b class='flag-5'>內(nèi)存</b><b class='flag-5'>占用</b>案例分析:Driver Locked

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

    如何理解JSON數(shù)據(jù)?作為NoSQL數(shù)據(jù)的一種類型,JSON數(shù)據(jù)有哪些優(yōu)勢(shì)呢?JSON數(shù)據(jù)
    的頭像 發(fā)表于 12-02 08:04 ?687次閱讀
    什么是<b class='flag-5'>JSON</b>數(shù)據(jù)<b class='flag-5'>庫</b>

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

    如何理解JSON數(shù)據(jù)?作為NoSQL數(shù)據(jù)的一種類型,JSON數(shù)據(jù)有哪些優(yōu)勢(shì)呢?JSON數(shù)據(jù)
    的頭像 發(fā)表于 12-06 13:46 ?711次閱讀
    關(guān)于<b class='flag-5'>JSON</b>數(shù)據(jù)<b class='flag-5'>庫</b>