Json性能测试——cJSON vs rapidjson

测试环境:

Intel(R) Xeon(R) CPU E5-2650 v2 @ 2.60GHz
MemTotal: 65938376 kB
CentOS release 6.7 (Final)
gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17)

结论

在-O3的编译环境下,rapidjson的性能应该是cJSON的2.4-3.5倍左右

注:
1、如果换成-O0 则cJSON性能比较好
2、不同的json文件,时间差异比较大

运行结果

cJSON性能

#./a.out json/1.json 100000
read file: json/1.json, loop count: 100000
cost time: 3910475 us, 25572.34 pps

# ./a.out json/test1 1000000
read file: json/test1, loop count: 1000000
cost time: 8368924 us, 119489.67 pps

rapidjson性能

# ./a.out json/1.json 100000
read file: json/1.json, loop count: 100000
cost time: 1099633 us, 90939.43 pps

# ./a.out json/test1 1000000
read file: json/test1, loop count: 1000000
cost time: 3407460 us, 293473.73 pps

测试代码

需要先clone出对应的解析依赖
https://github.com/DaveGamble/cJSON
https://github.com/miloyip/rapidjson

cJSON代码示例

#include 
#include 
#include 
#include 

#include "cJSON.h"

char *data = NULL;

/* Read a file, parse, render back, etc. */
void dofile(char *filename)
{
    FILE *f = NULL;
    long len = 0;

    /* open in read binary mode */
    f = fopen(filename,"rb");
    /* get the length */
    fseek(f, 0, SEEK_END);
    len = ftell(f);
    fseek(f, 0, SEEK_SET);

    data = (char*)malloc(len + 1);

    fread(data, 1, len, f);
    data[len] = '\0';
    fclose(f);
}


/* Parse text to JSON, then render back to text, and print! */
void doit(char *text)
{
    char *out = NULL;
    cJSON *json = NULL;

    json = cJSON_Parse(text);
    if (!json) {
        printf("Error before: [%s]\n", cJSON_GetErrorPtr());
    } else {
        cJSON_AddStringToObject(json, "author", "[email protected]");
        out = cJSON_Print(json);
        cJSON_Delete(json);
        //printf("%s\n", out);
        free(out);
    }
}

int main(int argc, char *argv[])
{
    int i = 0;
    struct timeval start, end;

    if (argc < 3) {
        printf("Usage: %s  , argv[0]);
        exit(0);
    }

    char *file = argv[1];
    int loop = atoi(argv[2]);
    printf("read file: %s, loop count: %d\n", file, loop);

    dofile(file);

    gettimeofday(&start, NULL);
    for (i = 0; i < loop; i++) {
        doit(data);
    }
    gettimeofday(&end, NULL);

    uint64_t time_cost = ((end.tv_sec - start.tv_sec) * 1000000 + \
            end.tv_usec - start.tv_usec);

    printf("cost time: %ld us, %.2f pps\n", time_cost, loop / (time_cost * 1.0) * 1000000);
}

rapidjson代码示例

#include 
#include 
#include 
#include 
#include 
#include 

#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"

using namespace std;
using namespace rapidjson;

using std::ifstream;
using rapidjson::Value;
using rapidjson::Document;


string dofile(const char *filename) {
    ifstream in;
    in.open(filename, ifstream::in);
    if (!in.is_open()) {
        return NULL;
    }

    string line;
    string stringFromStream;
    while (getline(in, line)) {
        stringFromStream.append(line + "\n");
    }
    in.close();

    return stringFromStream;
}


void doit(string stringFromStream) {
    Document doc;
    doc.Parse<0>(stringFromStream.c_str());
    if (doc.HasParseError()) {
        rapidjson::ParseErrorCode code = doc.GetParseError();
        std::cout << code << std::endl;
        return;
    }

//    Value &varInt = doc["sort"][0];
//    if (varInt.IsInt64()) {
//        int64_t count = varInt.GetInt64();
//        varInt.SetInt64(count + 1);
//    }
//
//    Value &varString = doc["_id"];
//    if (varString.IsString()) {
//        string var = varString.GetString();
//        varString.SetString("1234567890dsdsddsds");
//    }
    doc.AddMember("author", "[email protected]", doc.GetAllocator());

    StringBuffer buffer;
    Writer writer(buffer);
    doc.Accept(writer);

    //std::cout << buffer.GetString() << std::endl;
}


int main(int argc, char *argv[]) {
    int i = 0;
    struct timeval start, end;

    char *file = argv[1];
    int loop = atoi(argv[2]);
    printf("read file: %s, loop count: %d\n", file, loop);

    string stringFromStream = dofile(file);
    //cout << stringFromStream << endl;

    gettimeofday(&start, NULL);
    for (i = 0; i < loop; i++) {
        doit(stringFromStream);
    }
    gettimeofday(&end, NULL);

    uint64_t time_cost = ((end.tv_sec - start.tv_sec) * 1000000 + \
            end.tv_usec - start.tv_usec);

    printf("cost time: %ld us, %.2f pps\n", time_cost, loop / (time_cost * 1.0) * 1000000);

    return 0;
}

JSON文件

#cat 1.json
{
    "_index": "cc-cloudsensor-4a859fff6e5c4521aab187eee1cfceb8-2016.12.14",
        "_type": "http",
        "_id": "AVj-D8OzyUc7ekFJUXpB",
        "_score": null,
        "_timestamp": 1481731195827,
        "_source": {
            "@timestamp": "2016-12-14T23:59:55+08:00",
            "aggregate_count": 1,
            "appname": "cloudsensor",
            "dawn_ts0": 1481731195311000,
            "dawn_ts1": 1481731195311000,
            "device_id": "be8bb0ff-c73a-5ca6-afd8-871783d8b890",
            "fair_handle_latency_us": 105,
            "fair_ts0": 1481731195391680,
            "fair_ts1": 1481731195391785,
            "guid": "4a859fff6e5c4521aab187eee1cfceb8",
            "host": "list.com",
            "http": {
                "dst_ip": {
                    "decimal": 2362426130,
                    "dotted": "140.207.195.18",
                    "isp": "联通",
                    "latitude": "121.472644",
                    "longtitude": "31.231706",
                    "raw": 2362426130,
                    "region": "上海"
                },
                "dst_port": 80,
                "host": "passport.bdimg.com",
                "http_method": 1,
                "https_flag": 0,
                "in_bytes": 305,
                "in_pkts": 1,
                "l4_protocol": "tcp",
                "latency_sec": 0,
                "latency_usec": 215779,
                "out_bytes": 675,
                "out_pkts": 1,
                "refer": "",
                "src_ip": {
                    "decimal": 176189498,
                    "dotted": "10.128.112.58",
                    "isp": "",
                    "latitude": "",
                    "longtitude": "",
                    "raw": 176189498,
                    "region": ""
                },
                "src_port": 38558,
                "status_code": 200,
                "url": "/passApi/html/sdkloginconfig.html",
                "url_query": "",
                "user_agent": {
                    "raw": ""
                },
                "xff": ""
            },
            "kafka": {
                "offset": 83107248,
                "partition": 0,
                "topic": "cloudsensor"
            },
            "probe": {
                "hostname": "list.com",
                "name": "cloudsensor"
            },
            "probe_ts": 1481731310,
            "topic": "cloudsensor",
            "type": "http"
        },
        "fields": {
            "@timestamp": [
                1481731195000
            ]
        },
        "highlight": {
            "type": [
                "@kibana-highlighted-field@http@/kibana-highlighted-field@"
            ]
        },
        "sort": [
            1481731195000
        ]
}


#cat test1
{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

附录

Json性能测试——cJSON vs rapidjson_第1张图片

  1. https://github.com/miloyip/nativejson-benchmark

你可能感兴趣的:(Json性能测试——cJSON vs rapidjson)