首页IT科技jsonp实现原理解析(JsonCpp使用优化)

jsonp实现原理解析(JsonCpp使用优化)

时间2025-09-19 14:36:25分类IT科技浏览6374
导读:最近一个项目在使用JsonCpp,JsonCpp简洁易用的接口让人印象深刻。但是在实际使用过程中,我发现JsonCpp的性能却不尽如人意,所以想着方法优化下性能。...

最近一个项目在使用JsonCpp                ,JsonCpp简洁易用的接口让人印象深刻                。但是在实际使用过程中                      ,我发现JsonCpp的性能却不尽如人意        ,所以想着方法优化下性能                      。

代码理解

1              、JsonCpp中一切都是Value            ,Value用union指向自己保存的数据        。Value的类型分为两种                      ,一种是容器类型            ,比如arrayValue和objectValue            。二者都是用map保存数据        ,只是arrayValue的key为数字而已                      。另外一种是基本类型                      ,比如字符串               ,整型数字等等            。

2                        、解释JSON数据时    ,JsonCpp在operator[]函数开销比较大        。JsonCpp内部使用std::map                       ,查找性能方便                  ,map不如hash_map,但是将map替换成hash_map有一定的困难                    ,因为map的key为CZString                      ,而这个类又是Value的内部类    ,导致不能定义hash_map需要的hash结构体                      。

本来想尝试下internal map                ,结果开启JSON_VALUE_USE_INTERNAL_MAP这个宏之后                      ,根本通不过编译        ,因为value.h中有一处uion声明里面居然放的是结构体            ,不知道什么编译器支持这种语法               。

基准测试程序

+ expand source帮助
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <iostream>
#include <string>
#include <sys/time.h>
#include <time.h>
#include <json/json.h>
using namespace std;
int64_t getCurrentTime()
{
struct timeval tval;
gettimeofday(&tval, NULL);
return (tval.tv_sec * 1000000LL + tval.tv_usec);
}
char * str = "abcdefghijklmnopqrstuvwxyz";
void test1()
{
int doc_count = 40;
int outer_field_count = 80;
Json::Value common_info;
int64_t start_time = getCurrentTime();
for(size_t i=0; i<doc_count; ++i)
{
Json::Value auc_info;
for( size_t j=0 ; j<outer_field_count; ++j )
{
auc_info.append(str);
}
common_info.append(auc_info);
}
int64_t end_time = getCurrentTime();
cout << "append time: " << end_time - start_time << endl;
}
void test2()
{
int doc_count = 40;
int outer_field_count = 80;
Json::Value common_info;
int64_t start_time = getCurrentTime();
Json::Value auc_info;
for(size_t i=0; i<doc_count; ++i)
{
for( size_t j=0 ; j<outer_field_count; ++j )
{
auc_info[j] = str;
}
common_info.append(auc_info);
}
int64_t end_time = getCurrentTime();
cout << "opt append time: " << end_time - start_time << endl;
}
void test3()
{
int doc_count = 40;
int outer_field_count = 80;
Json::Value common_info;
int64_t start_time = getCurrentTime();
Json::Value auc_info;
for(size_t i=0; i<doc_count; ++i)
{
for( size_t j=0 ; j<outer_field_count; ++j )
{
auc_info[j] = Json::StaticString(str);
}
common_info.append(auc_info);
}
int64_t end_time = getCurrentTime();
cout << "StaticString time: " << end_time - start_time << endl;
}
int main(int argc, const char *argv[])
{
test1();
test2();
test3();
return 0;
}

编译优化

默认情况下                      ,JsonCpp编译时并没有带优化参数            ,自己可以加上优化参数    。Linux环境下在下面这段代码中的CCFLAGS加入                ”O2″                       。

1
2
3
4
elif platform.startswith(linux-gcc):
env.Tool( default )
env.Append( LIBS = [pthread], CCFLAGS = "-Wall -fPIC O2" )
env[SHARED_LIB_ENABLED] = True

可以看到使用O2优化比默认编译的版本性能提升一倍多                  。

1
2
3
4
5
6
7
append time: 4946
opt append time: 3326
StaticString time: 2750
append time: 1825
opt append time: 1082
StaticString time: 845

使用方法上的优化

测试代码中第三种方法比第一种方法效率提升了一倍多。第三种方法之所以效率更高        ,有两个原因                    。

1        、首先是在循环中一直复用auc_info对象                      。第一个循环就能将auc_info的长度初始化为doc_count    。通过下标的访问方法                      ,一直复用数组中的元素                。

2          、如果key和value内存不会被释放               ,那么使用StaticString效率会更高    ,省去了构造CZString时拷贝的开销                      。

代码优化

因为在JsonCpp中一切都是Value                       ,所以会有大量的隐性类型转换                  ,要构造大量的Value对象        。为了提高性能,可以在实现绕过这个机制                    ,牺牲一致性            。

因为Value最常用的类型是字符串                      ,因此给Value增加一个setValue函数                      。

1
2
3
4
5
6
7
void
Value::setValue( const StaticString& value )
{
type_ = stringValue;
allocated_ = false;
value_.string_ = const_cast<char *>( value.c_str() );
}

再测试一下性能    ,可以发现性能较第三种方法还有提升            。

1
2
3
4
append time: 1849
opt append time: 1067
StaticString time: 843
setValue time: 570

最后还有一个办法就是静态链接        。JsonCpp库本身非常小                ,将其静态链接能稍微提升一点性能                      。下面是静态链接时基准测试程序的耗时情况               。

1
2
3
4
append time: 1682
opt append time: 1011
StaticString time: 801
setValue time: 541
声明:本站所有文章                      ,如无特殊说明或标注        ,均为本站原创发布    。任何个人或组织            ,在未征得本站同意时                      ,禁止复制                        、盗用            、采集      、发布本站内容到任何网站                       、书籍等各类媒体平台                       。如若本站内容侵犯了原著者的合法权益            ,可联系我们进行处理                  。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
seo搜索引擎实战详解(掌握SEO,助你站在搜索引擎前沿)