json opt

 rapidjson 比jsoncpp更快

#include <types.h>
#include <json/json.h>
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <iostream>
#include <list>
#include <chrono>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <jsonComOpt.h>
uint64_t systemNowMs()
{
    struct timespec tnow;
    clock_gettime(CLOCK_MONOTONIC, &tnow);
    return (uint64_t)(tnow.tv_sec) * 1000 + tnow.tv_nsec / 1000000;
}

struct lxcheckstruct
{
    std::string name;
    int age;
    int c;
    std::string addr;
    std::string id;
    std::string remain[10];
};
#define JSON_CHECK_SIZE 5
int main() {
    std::list<struct lxcheckstruct> tmplist;
    struct lxcheckstruct tmplx;
    uint64_t tmpTimeMs = systemNowMs();    
    rapidjson::Document tmpdoc;
    tmpdoc.SetObject();    
    tmpdoc.AddMember("lxjson", rapidjson::Value(rapidjson::kStringType).SetString("list", tmpdoc.GetAllocator()), tmpdoc.GetAllocator());
    rapidjson::Value tmpArray;
    tmpArray.SetArray();
    for(int i = 0; i < JSON_CHECK_SIZE; i++)
    {
        tmplx.name = "lxin work name is :" + std::to_string(i);
        tmplx.age = i + 10;
        tmplx.c = i + 1000;
        tmplx.addr = "lxin addr place is :" + std::to_string(i);
        tmplx.id = "lxin card id is :" + std::to_string(i);
        rapidjson::Value tmpobj(rapidjson::kObjectType);
        tmpobj.AddMember("name", rapidjson::Value().SetString(tmplx.name.c_str(), tmpdoc.GetAllocator()), tmpdoc.GetAllocator());
        tmpobj.AddMember("age", rapidjson::Value().SetInt(tmplx.age), tmpdoc.GetAllocator());
        tmpobj.AddMember("c", rapidjson::Value().SetInt(tmplx.c), tmpdoc.GetAllocator());
        tmpobj.AddMember("addr", rapidjson::Value().SetString(tmplx.addr.c_str(), tmpdoc.GetAllocator()), tmpdoc.GetAllocator());
        tmpobj.AddMember("id", rapidjson::Value().SetString(tmplx.id.c_str(), tmpdoc.GetAllocator()), tmpdoc.GetAllocator());
        rapidjson::Value tmpRemain(rapidjson::kArrayType);
        for(size_t j = 0; j < sizeof(tmplx.remain) / sizeof(tmplx.remain[0]); j++)
        {
            tmplx.remain[j] = "lxin remain is :" + std::to_string(j);
            tmpRemain.PushBack(rapidjson::Value().SetString(tmplx.remain[j].c_str(), tmpdoc.GetAllocator()), tmpdoc.GetAllocator());
        }
        tmpobj.AddMember("remain", tmpRemain, tmpdoc.GetAllocator());
        tmpArray.PushBack(tmpobj, tmpdoc.GetAllocator());
    }
    tmpdoc.AddMember("lxdata", tmpArray, tmpdoc.GetAllocator());

    printf("mak time:%lums\n", systemNowMs() - tmpTimeMs);
    tmpTimeMs = systemNowMs();
    rapidjson::StringBuffer buffer;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    tmpdoc.Accept(writer);

    printf("to str time:%lums\n", systemNowMs() - tmpTimeMs);
    tmpTimeMs = systemNowMs();
    printf("data size :%lu\n", strlen(buffer.GetString()));
    if(JSON_CHECK_SIZE < 50)
    {
        std::cout << buffer.GetString() << std::endl;
    }

    rapidjson::Document tmpdoc1;
    tmpdoc1.Parse(buffer.GetString());
    printf("to json time:%lums\n", systemNowMs() - tmpTimeMs);
    tmpTimeMs = systemNowMs();
    ===jsoncpp==================================================================

    Json::Value tmpCJroot;
    tmpCJroot["lxjson"] = "list";
    Json::Value &tmpCJdata = tmpCJroot["lxdata"];
    for(int i = 0; i < JSON_CHECK_SIZE; i++)
    {
        tmplx.name = "lxin work name is :" + std::to_string(i);
        tmplx.age = i + 10;
        tmplx.c = i + 1000;
        tmplx.addr = "lxin addr place is :" + std::to_string(i);
        tmplx.id = "lxin card id is :" + std::to_string(i);
        Json::Value tmpobj;
        tmpobj["name"] = tmplx.name;
        tmpobj["age"] = tmplx.age;
        tmpobj["c"] = tmplx.c;
        tmpobj["addr"] = tmplx.addr;
        tmpobj["id"] = tmplx.id;
        for(size_t j = 0; j < sizeof(tmplx.remain) / sizeof(tmplx.remain[0]); j++)
        {
            tmplx.remain[j] = "lxin remain is :" + std::to_string(j);
            tmpobj["remain"].append(tmplx.remain[j]);
        }
        tmpCJdata.append(tmpobj);
    }
    printf("cj mak time:%lums\n", systemNowMs() - tmpTimeMs);
    tmpTimeMs = systemNowMs();
    std::string tmpCJstr = jsoncppComOptClass::jsonToString(tmpCJroot);
    printf("cj to str time:%lums\n", systemNowMs() - tmpTimeMs);
    tmpTimeMs = systemNowMs();
    printf("data size :%lu\n", tmpCJstr.size());
    if(JSON_CHECK_SIZE < 50)
    {
        std::cout << tmpCJstr.c_str() << std::endl;
    }

    Json::Reader tmpCJreader;
    Json::Value tmpCJparse;
    tmpCJreader.parse(tmpCJstr, tmpCJparse);
    printf("cj to json time:%lums\n", systemNowMs() - tmpTimeMs);
    tmpTimeMs = systemNowMs();

     Output {"project":"rapidjson","stars":11}
    
    // // 1. 把 JSON 解析至 DOM。
    // const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
    // rapidjson::Document d;
    // d.Parse(json);

    // // 2. 利用 DOM 作出修改。
    // rapidjson::Value& s = d["stars"];
    // // s.SetInt(s.GetInt() + 1);
    // s.SetString("21244");

    // // 3. 把 DOM 转换(stringify)成 JSON。
    // rapidjson::StringBuffer buffer;
    // rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
    // d.Accept(writer);

    // // Output {"project":"rapidjson","stars":11}
    // std::cout << buffer.GetString() << std::endl;
    return 0;
}

#if 0
长度5如下:
mak time:0ms
to str time:0ms
data size :1618
{"lxjson":"list","lxdata":[{"name":"lxin work name is :0","age":10,"c":1000,"addr":"lxin addr place is :0","id":"lxin card id is :0","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"name":"lxin work name is :1","age":11,"c":1001,"addr":"lxin addr place is :1","id":"lxin card id is :1","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"name":"lxin work name is :2","age":12,"c":1002,"addr":"lxin addr place is :2","id":"lxin card id is :2","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"name":"lxin work name is :3","age":13,"c":1003,"addr":"lxin addr place is :3","id":"lxin card id is :3","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"name":"lxin work name is :4","age":14,"c":1004,"addr":"lxin addr place is :4","id":"lxin card id is :4","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]}]}
to json time:0ms
cj mak time:1ms
cj to str time:0ms
data size :1618
{"lxdata":[{"addr":"lxin addr place is :0","age":10,"c":1000,"id":"lxin card id is :0","name":"lxin work name is :0","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"addr":"lxin addr place is :1","age":11,"c":1001,"id":"lxin card id is :1","name":"lxin work name is :1","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"addr":"lxin addr place is :2","age":12,"c":1002,"id":"lxin card id is :2","name":"lxin work name is :2","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"addr":"lxin addr place is :3","age":13,"c":1003,"id":"lxin card id is :3","name":"lxin work name is :3","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]},{"addr":"lxin addr place is :4","age":14,"c":1004,"id":"lxin card id is :4","name":"lxin work name is :4","remain":["lxin remain is :0","lxin remain is :1","lxin remain is :2","lxin remain is :3","lxin remain is :4","lxin remain is :5","lxin remain is :6","lxin remain is :7","lxin remain is :8","lxin remain is :9"]}],"lxjson":"list"}
cj to json time:0ms

长度10W如下:
mak time:495ms
to str time:1002ms
data size :33347638
to json time:1104ms
cj mak time:3999ms
cj to str time:2078ms
data size :33347638
cj to json time:4255ms
#endif

jsoncpp效率还是很高的,以下代码,将10000行*50列的数据打包,只需1秒。

int main()
{
    Json::Value outRoot;
    outRoot.clear();
    int i, j;
    logwdbg("");
    logwdbg("");
    Json::Value &tabVal = outRoot["tableStrName"];
    Json::Value &colsVal = tabVal["cols"];
    logwdbg("");
    for(i = 0; i < 50; i++)
    {
        colsVal.append("bafudlsfdfjlfeixfd" + to_string(i));
    }
    Json::Value &rowsVal = tabVal["rows"];
    Json::Value rowsColVal;
    for(j = 0; j < 10000; j++)
    {
        // logwdbg("");
        rowsColVal.clear();
        for(i = 0; i < 50; i++)
        {
            rowsColVal.append("tmpTableInfIter" + to_string(i));
        }
        rowsVal.append(rowsColVal);
    }
    logwdbg("");
    // Json::StyledWriter sw;
    // cout << sw.write(outRoot) << endl;
    return 1;
}

这里需要备注以下:

1.使用&引用的妙处,&在原对象上操作!快,用在解析和生成json:

    Json::Value &rowsVal = tabVal["rows"];
    Json::Value rowsColVal;
    for(j = 0; j < 10000; j++)
    {
        // logwdbg("");
        rowsColVal.clear();
        for(i = 0; i < 50; i++)
        {
            rowsColVal.append("tmpTableInfIter" + to_string(i));
        }
        rowsVal.append(rowsColVal);
    }
要比下面的代码快15%
    Json::Value rowsVal;
    Json::Value rowsColVal;
    for(j = 0; j < 10000; j++)
    {
        // logwdbg("");
        rowsColVal.clear();
        for(i = 0; i < 50; i++)
        {
            rowsColVal.append("tmpTableInfIter" + to_string(i));
        }
        rowsVal.append(rowsColVal);
    }
    tabVal["rows"] = rowsVal;
和下面代码快一点
    Json::Value rowsColVal;
    for(j = 0; j < 10000; j++)
    {
        // logwdbg("");
        rowsColVal.clear();
        for(i = 0; i < 50; i++)
        {
            rowsColVal.append("tmpTableInfIter" + to_string(i));
        }
        tabVal["rows"].append(rowsColVal);
    }

2.如果json表示表格,可以参考以下格式:

{
   "tableStrName" : {
      "cols" : [
         "WeekPlanID",
         "WeekDay",
         "TimeStart",
         "TimeEnd"
      ],
      "rows" : [
         [
            "Iter0",
            "Iter1",
            "tIter2",
            "Iter3"
         ],
         [
            "Iter0",
            "Iter1",
            "Iter2",
            "Iter3"
         ]
      ]
   }
}
要比下面方式节约空间,并且效率也会提高:用上面的测试10万*10,空间减少一半,效率提高50%
{
    "TabWeek":[
        {
            "WeekPlanID":"1",
            "WeekDay":"1",
            "TimeStart":"00:00",
            "TimeEnd":"23:59"
        },
        {
            "WeekPlanID":"1",
            "WeekDay":"2",
            "TimeStart":"00:00",
            "TimeEnd":"23:59"
        },
        {
            "WeekPlanID":"1",
            "WeekDay":"3",
            "TimeStart":"00:00",
            "TimeEnd":"23:59"
        }
    ]
}

3.Json::FastWriter转换为字符串后,中文为乱码问题,通过自定义构建即可,参考如下,commentStyle和indentation为了减少换行符和空格

    static std::string jsonToString(const Json::Value &root)
    {
        static Json::Value def = []() {
            Json::Value def;
            Json::StreamWriterBuilder::setDefaults(&def);
            def["emitUTF8"] = true;
            def["commentStyle"] = "None";
            def["indentation"] = "";
            return def;
        }();

        std::ostringstream stream;
        Json::StreamWriterBuilder stream_builder;
        stream_builder.settings_ = def; //Config emitUTF8
        std::unique_ptr<Json::StreamWriter> writer(stream_builder.newStreamWriter());
        writer->write(root, &stream);
        return stream.str();
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值