前言

本篇对cjson,rapidjson,yyjson三种json反序列化工具的性能进行对比。

有json样本数据如下:

实验环境:

cpu:Xeon

cpu主频:2.20GHz 

以下示例均未对字段的安全性进行检查。各示例的字段安全性检查参考json系列第一篇“cjson,rapidjson,yyjson解析示例”。

一、cjson反序列化性能

 1 #include<stdio.h>
 2 #include<sys/time.h>
 3 
 4 #include"cJSON.h"
 5 
 6 // g++ -g -o cjson_speed_test -std=c++11 cjson_speed_test.c cJSON.c
 7 
 8 int main()
 9 {
10     int cnt = 0;
11     timeval st, et;
12     
13     cJSON *json_root;
14     char str_buf[1024] = "{\"uri\":\"/uriCSh56j30cbGa\",\"host\":\"www.baidu.com\",\"uagent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"resp_content_type\":\"video/fli\",\"status\":200,\"resp_content_length\":20480,\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"traffic_id\":1057153235624398,\"protocol\":\"http\",\"src_ip\":\"112.1.101.40\",\"src_port\":22291,\"dst_ip\":\"112.2.81.190\",\"dst_port\":80,\"random_code\":7449212903698783717,\"feature_code\":\"y0BMEwnJ7RFICUAC5FKYkStTLVw=\"}";
15 
16     gettimeofday(&st, NULL);
17     while(1) {
18         json_root = cJSON_Parse(str_buf);
19         
20         cJSON_GetObjectItem(json_root, "protocol");
21         cJSON_GetObjectItem(json_root, "uri");
22 
23         cJSON_GetObjectItem(json_root, "host");
24         cJSON_GetObjectItem(json_root, "uagent");
25 
26         cJSON_GetObjectItem(json_root, "src_port");
27         cJSON_GetObjectItem(json_root, "dst_port");
28 
29         cJSON_GetObjectItem(json_root, "timestamp");
30         cJSON_GetObjectItem(json_root, "feature_code");
31 
32         cJSON_GetObjectItem(json_root, "src_ip");
33         cJSON_GetObjectItem(json_root, "dst_ip");
34 
35         cJSON_GetObjectItem(json_root, "traffic_id");
36         cJSON_GetObjectItem(json_root, "random_code");
37 
38         cJSON_Delete(json_root);
39         
40         cnt++;
41         gettimeofday(&et, NULL);
42         if(et.tv_sec - st.tv_sec >= 10) {
43             break;
44         }
45     }
46 
47     printf("deserialization per second:%d\n", cnt/10);
48     return 0;
49 }

 反序列化性能:

 二、rapidjson反序列化性能

rapidjson有两种解析方法,一种是Parse,另一种是ParseInsitu(原位解析)。区别在于ParseInsitu不需要进行malloc操作,在原来的字符串空间中进行字符串反序列化,弊端是原来的字符串会被修改。这里选用Parse方法。

 1 #include<stdio.h>
 2 #include<sys/time.h>
 3 
 4 #include "rapidjson/rapidjson.h"
 5 #include "rapidjson/document.h"
 6 #include "rapidjson/stringbuffer.h"
 7 #include "rapidjson/writer.h"
 8 
 9 // g++ -g -o rapidjson_speed_test -std=c++11 rapidjson_speed_test.c
10 
11 int main()
12 {
13     int cnt = 0;
14     timeval st, et;
15     
16     char str_buf[1024] = "{\"uri\":\"/uriCSh56j30cbGa\",\"host\":\"www.baidu.com\",\"uagent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"resp_content_type\":\"video/fli\",\"status\":200,\"resp_content_length\":20480,\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"traffic_id\":1057153235624398,\"protocol\":\"http\",\"src_ip\":\"112.1.101.40\",\"src_port\":22291,\"dst_ip\":\"112.2.81.190\",\"dst_port\":80,\"random_code\":7449212903698783717,\"feature_code\":\"y0BMEwnJ7RFICUAC5FKYkStTLVw=\"}";
17     char str_buf_tmp[1024] = {0};
18 
19     rapidjson::Document parse_doc;
20 
21     gettimeofday(&st, NULL);
22     while(1) {
23     
24         parse_doc.Parse(str_buf);
25         parse_doc.FindMember("protocol")->value.GetString();
26         parse_doc.FindMember("uri")->value.GetString();
27         
28         parse_doc.FindMember("host")->value.GetString();
29         parse_doc.FindMember("resp_content_type")->value.GetString();
30         
31         parse_doc.FindMember("src_port")->value.GetInt();
32         parse_doc.FindMember("dst_port")->value.GetInt();
33         
34         parse_doc.FindMember("timestamp")->value.GetString();
35         parse_doc.FindMember("feature_code")->value.GetString();
36         
37         parse_doc.FindMember("src_ip")->value.GetString();
38         parse_doc.FindMember("dst_ip")->value.GetString();
39 
40         parse_doc.FindMember("traffic_id")->value.GetUint64();
41         parse_doc.FindMember("random_code")->value.GetUint64();
42 
43         cnt++;
44         gettimeofday(&et, NULL);
45         if(et.tv_sec - st.tv_sec >= 10) {
46             break;
47         }
48     }
49 
50     printf("deserialization per second:%d\n", cnt/10);
51     return 0;
52 }

 反序列化性能:

 三、yyjson反序列化性能

 1 #include<stdio.h>
 2 #include<sys/time.h>
 3 
 4 #include "yyjson.h"
 5 
 6 // g++ -g -o yyjson_speed_test -std=c++11 yyjson_speed_test.c yyjson.c
 7 
 8 int main()
 9 {
10     int cnt = 0;
11     timeval st, et;
12     
13     long value2;
14     char str_buf[1024] = "{\"uri\":\"/uriCSh56j30cbGa\",\"host\":\"www.baidu.com\",\"uagent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"resp_content_type\":\"video/fli\",\"status\":200,\"resp_content_length\":20480,\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"traffic_id\":1057153235624398,\"protocol\":\"http\",\"src_ip\":\"112.1.101.40\",\"src_port\":22291,\"dst_ip\":\"112.2.81.190\",\"dst_port\":80,\"random_code\":7449212903698783717,\"feature_code\":\"y0BMEwnJ7RFICUAC5FKYkStTLVw=\"}";
15 
16     gettimeofday(&st, NULL);
17     while(1) {
18 
19         yyjson_doc *doc = yyjson_read(str_buf, strlen(str_buf), 0);
20         yyjson_val *root = yyjson_doc_get_root(doc);
21 
22         yyjson_get_str(yyjson_obj_get(root, "protocol"));
23         yyjson_get_str(yyjson_obj_get(root, "uri"));
24 
25         yyjson_get_str(yyjson_obj_get(root, "host"));
26         yyjson_get_str(yyjson_obj_get(root, "uagent"));
27 
28         yyjson_get_int(yyjson_obj_get(root, "src_port"));
29         yyjson_get_int(yyjson_obj_get(root, "dst_port"));
30 
31         yyjson_get_str(yyjson_obj_get(root, "timestamp"));
32         yyjson_get_str(yyjson_obj_get(root, "feature_code"));
33         
34         yyjson_get_str(yyjson_obj_get(root, "src_ip"));
35         yyjson_get_str(yyjson_obj_get(root, "dst_ip"));
36 
37         yyjson_get_uint(yyjson_obj_get(root, "traffic_id"));
38         yyjson_get_uint(yyjson_obj_get(root, "random_code"));
39 
40         yyjson_doc_free(doc);
41 
42         cnt++;
43         gettimeofday(&et, NULL);
44         if(et.tv_sec - st.tv_sec >= 10) {
45             break;
46         }
47     }
48 
49     printf("deserialization per second:%d\n", cnt/10);
50     return 0;
51 }

 反序列化性能:

 四、结论

yyjson的反序列化高性能真是让我感到欣喜,是cjson三倍以上、rapidjson Parse方法的10倍以上。若编译添加-O2优化参数,yyjson的测试结果更加惊喜,并且yyjson的cpu使用率更低。

另外,yyjson的序列化性能也是三者中最高的。

推荐大家使用yyjson!

 

本文来自博客园,作者:T-BARBARIANS,转载请注明原文链接:https://www.cnblogs.com/t-bar/p/15722726.html 谢谢!