别再推荐使用 jsoncpp 了
创始人
2024-02-22 17:52:45
0

文章目录

    • 事件起因
    • 为什么不推荐jsoncpp
    • json解析如何优化性能

事件起因

今天刷视频看到一位大佬写的json解析库的性能超群,秒杀了一众 json 解析库,其中包括我比较喜欢的 nlohmann json 库,这个库在他的测试中性能垫底,我曾写过一个 json 解析库,性能的对比对象就是这个库,我记得是略有不如。所以我第一时间想到的是不是测试有问题,nlohmann json 不可能这么慢啊,明明用到了大量模板的魔法😨,然后我就亲自把 nlohmann jsonjsoncpp 以及大佬的库都测了一遍。

为什么不推荐jsoncpp

如果有用过 jsoncpp 的,以及其他语言的json库的,我觉得都会认为 jsoncpp 的api也太难用了吧。。。

但是如果这一切都是为了性能,那么还是有选择余地的,但如果 jsoncpp 的复杂并没有带来实质性的性能提升,那么我们为什么不用更简单好用性能也更佳的 nlohmann json 呢?

以下为测试源码:Timer类用于计时

#include "time.hpp"
#include 
#include 
#include 
using namespace std;
#include "nlohmann/json.hpp"
using json_nl = nlohmann::json;#include"json/json.h"
using Value = Json::Value;
using Reader = Json::Reader;#include "Json.h"#include "my-json/Parser.h"
using my_parser = json::Parser;//用于调整测试和验证文件的路径
#define BASE_DIR  "../../"//输出到valid.json文件方便查看验证是否解析正确
void outPutValidJson(std::string const& src){auto ofs = ofstream(BASE_DIR"valid.json");ofs<auto ifs = ifstream(BASE_DIR"test.json");if(ifs){return string{istreambuf_iterator(ifs),istreambuf_iterator()};}return {};
}//测试yaziJson的表现
void testYaziJson()
{//get src stringauto data = getSourceString();yazi::json::Json json;//start bench{Timer t;json.parse(data);}//valid stringoutPutValidJson(json.str());
}//测试nlohmannJson的表现
void testNlohmannJson()
{//get src stringauto data = getSourceString();json_nl j;//start bench{Timer t;j = std::move(json_nl::parse(data));}//valid stringoutPutValidJson(j.dump());
}//测试jsoncpp的表现
void testJsonCpp(){//get src stringauto data = getSourceString();Value j;Reader r;//start bench{Timer t;if(!r.parse(data,j)){std::cerr<<"jsoncpp 出错";return;}}//valid stringoutPutValidJson(j.toStyledString());
}//测试我的json解析库的表现
void testMyJson(){//get src stringauto data = getSourceString();json::JObject j;//start bench{Timer t;j = std::move(my_parser::FromString(data));}//valid stringoutPutValidJson(j.to_string());
}int main()
{for(int i=0;i<10;i++){testYaziJson();testMyJson();testJsonCpp();testNlohmannJson();std::cout<<"-----------------------"<

代码仓库:bench_json4cpp

平均10次结果:

yazi-json: 482 us (0.482000 ms) my-json: 518 us (0.518000 ms) json-cpp: 1046 us (1.046000 ms) nlohmann-json: 884 us (0.884000 ms)

大佬写的那个库确实是最快的,但是最慢的不是 nlohmann json, 而是 jsoncpp。而且差距也没有大佬视频里面那么大,两倍的差距而已,这对于一个浅拷贝和深拷贝的性能差距是很正常的。我估计大佬那里测试的时候没开 release 优化(对应 g++ -o3 优化,看了源码,果然大佬是直接写 makefile 里面的 flag 用的 -o2 优化),那么他视频里的性能差距就很正常了,因为在没开 release 优化的前提下,某个库如果大量用到 STL 以及元模板编程的时候,STL 会拖后腿,而元模板也没法发挥最大效用。所以最终用于生产开 release 是很有必要的。

举个简单的例子:在大家的印象中 make_uniquemake_shared 创建智能指针会优化减少一次拷贝,那么相比直接 new 对象性能肯定会更好,你可以试试,实际测试中如果是 debug 情况下,直接 new 大概率会更快,但是切到 release 模式两者效率都有进步,但 make 系列函数调用的优化会更多。

json解析如何优化性能

C++ json解析的性能瓶颈就在于 std::string 等STL容器默认的拷贝行为,一个简单粗暴的优化方式就是通过传指针的方式而不是传值的方式,但是这样外界就需要来管理内存了,否则会产生内存泄漏等问题。前面那个大佬写的库处理方式就是这样的。

熟悉cpp的朋友,大概率想到避免拷贝的方式就是移动,只要强制对象只能移动不能拷贝就行了。

洞察我之前写的 json 解析库,发现还有一个地方经常需要拷贝,而且还没法避免。string 类型的 substr 方法,所以我换成了string_view。这样在内部使用的内存和外界就一致了,这就需要用户确保这个内存不会被修改或回收。传入字符串进行解析很明显不应该拥有所有权,即便拥有也应该把外界的内存移动进来,所以采取string_view则是不拥有所有权的方式优化。同时还有个好处就是兼容了C-style字符串。

具体实现代码:my-json

相关内容

热门资讯

求20世纪90年代的动画片,国... 求20世纪90年代的动画片,国产和国外的都行!宫崎骏:红猪,倾耳倾听
基因重组的原理是什么? 基因重组的原理是什么?等位基因的分离与重组同源染色体分离等位基因重新组合基因重组是指一个DNA序列是...
在威海学英语哪所学校比较好? 在威海学英语哪所学校比较好?威海易兹国际语言学校不错,可以去看看。个人觉不同年龄段的人群学习语言是要...
自考护理学专业以后,可以考研吗... 自考护理学专业以后,可以考研吗?如果可以都可以考哪些专业的啊!如果你自考本科毕业的,是可以考研的,而...
蚕的一生有几个阶段每个阶段大约... 蚕的一生有几个阶段每个阶段大约有几天四个阶段,卵——幼虫——蛹——成虫, 共四十多天的时间。蚕期一龄...
秦时明月之诸子百家月儿结局怎么... 秦时明月之诸子百家月儿结局怎么样月儿到底怎么了,俄很想知道诸子百家还没出吧?月儿在夜尽天明里被月神带...
算命的说我有仙根,让我供大仙,... 算命的说我有仙根,让我供大仙,这是真的吗?算命的说我有仙根,让我供大仙,这是真的吗?可以 挺好的 可...
我为什么玩英雄联盟总是掉线..... 我为什么玩英雄联盟总是掉线...您好,一方面可能是您的网络不太稳定,造成掉线,可以检查一下网络是否正...
女人是怎样上厕所的 女人是怎样上厕所的 ,,,当然是蹲着了,不管大小都要带纸,明白了么,呵
简述游戏对儿童认知发展的作用是... 简述游戏对儿童认知发展的作用是什么?简述游戏对儿童认知发展的作用是什么? 游戏能有效地促进幼儿认知、...
离别的诗小学 离别的诗小学1、直道相思了无益,未妨惆怅是清狂。2、执手相看泪眼,竟无语凝噎。3、曾经沧海难为水,除...
《女神异闻录5》结局是什么? 《女神异闻录5》结局是什么? 《女神异闻录5》结局是永不落幕。莲被报道作为怪盗团事件的嫌疑犯而自杀的...
为什么会有戚顾同人的? 为什么会有戚顾同人的?为什么会有戚顾同人的??逆水寒为什么会有戚顾王道??是不是本身剧情就存在暧昧?...
关于篮球的词语 关于篮球的词语篮板、得分 、断球、发球形容篮球的词语比较常见的有雷霆万钧 千钧一发 球迷: 万众一心...
迈康立接骨木莓的食用方法? 迈康立接骨木莓的食用方法?食用方法可自主选择。关键是注意温度不要过高,这样容易破坏营养成分活性。以下...
求音乐:如果奥特曼打不赢小怪兽 求音乐:如果奥特曼打不赢小怪兽歌名应为 万一奥特曼打不赢小怪兽 歌手:小贱 专辑:我是小贱
数学动物园主要内容 数学动物园主要内容18算数有关的故事,里面的人物有小熊、小猴、老山羊、狐狸、黄鼠狼、虎大王、蛇和小灰...
请问有否可能超越光速?如果超越... 请问有否可能超越光速?如果超越了光速会后破坏物理规则。理论上可以 但是现在做不到 不会破坏物理...
心里总是很压抑,好想发泄一下,... 心里总是很压抑,好想发泄一下,但不知道该怎么去发泄,有没有好的建议啊?跳水,蹦机做一些挑战自己的运动
有关纪晓岚的长而幽默故事 有关纪晓岚的长而幽默故事拥抱 著名法国幽默作家特里斯坦·贝尔纳有一天去一家饭馆吃饭,对那里的服务态度...