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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/time.h>

#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", "yayun.tian@wxjuyun.com");
        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 <json-file> <loop-count\n", 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 <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <stdint.h>
#include <sys/time.h>

#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", "yayun.tian@wxjuyun.com", doc.GetAllocator());

    StringBuffer buffer;
    Writer<StringBuffer> 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"
                }
            }
        }
    }
}

附录

来自github的对比

  1. https://github.com/miloyip/nativejson-benchmark
### 关于 `core_.c` 文件的详解 #### C语言中的JSON处理概述 JSON作为一种轻量级的数据交换格式,被广泛应用在各种编程环境中。虽然JSON最初是作为JavaScript的一部分发展起来的,但它已经成为一种独立的语言无关的文本格式[^1]。 对于C语言而言,处理JSON通常依赖第三方库的支持。常见的做法是在项目中引入专门用于解析和生成JSON数据的库文件,比如Jansson、 cJSON 或者 RapidJSON等。这些库提供了丰富的函数接口来操作JSON对象,使得开发者可以在不直接面对复杂语法的情况下完成对JSON结构的操作。 #### `core_.c` 文件的作用与功能剖析 假设`core_.c`是一个涉及核心逻辑实现的关键模块,则其可能承担着如下职责: - **初始化配置**:负责加载应用程序启动所需的各项设置参数; - **资源管理**:管理和分配程序运行期间所需的各种硬件/软件资源; - **业务流程控制**:定义并执行主要的工作流路径; - **错误恢复机制**:当遇到异常情况时采取适当措施以保障系统的稳定性和可靠性; 具体到如何在这个上下文中处理JSON,这取决于实际应用场景的需求。如果确实存在这样的需求,那么很可能通过调用前述提及的那种专用库来进行编码解码工作。 #### 源码分析示例 为了更好地理解`core_.c`是如何工作的,下面给出一段简化版伪代码片段展示了一个简单的场景——读取来自外部源(如网络请求或其他进程间通讯渠道)传入的JSON字符串,并将其转换成内部使用的数据结构形式以便进一步加工利用。 ```c #include <stdio.h> #include "json_parser_library.h" // 假设这是一个支持JSON解析的头文件 int main() { char* json_input = "{\"key\":\"value\"}"; // 来自外界输入的JSON串 struct parsed_data pd; // 定义存储解析后结果的目标容器 int parse_status = parse_json(json_input, &pd); // 调用解析器进行转化 if (parse_status == SUCCESS){ printf("Parsed successfully.\n"); use_parsed_data(&pd); // 对已解析的内容做后续处理... } cleanup(); // 清理释放不再需要占用的空间 } ``` 这段代码展示了基本思路,即先获取原始JSON文本,再借助特定工具包对其进行解释得到易于计算机理解和操作的形式,最后根据具体情况决定下一步动作。 #### 使用教程要点提示 针对想要深入了解`core_.c`及其关联组件的人士来说,建议关注以下几个方面: - 学习所采用的具体JSON处理器件文档说明,熟悉API列表及最佳实践指南; - 掌握调试技巧,能够有效定位潜在问题所在位置; - 参考官方样例工程或者其他开源社区贡献的成功案例加深感官认知; - 不断积累经验教训,形成自己的一套高效开发模式。 #### 常见问题解答 关于`core_.c`以及其中涉及到的JSON处理部分可能会碰到的问题有: - 如何选择合适的JSON库? 应考虑性能指标、易用程度、跨平台兼容性等因素综合评判。 - 解析失败怎么办? 需仔细检查输入合法性,同时查看是否有版本冲突或是环境变量缺失等问题影响正常运作。 - 性能瓶颈怎么优化? 尝试减少不必要的内存拷贝次数,合理规划缓存策略,必要时可尝试多线程并发加速运算速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值