处理 JSON 数据的C++开发包:JsonCpp使用优化
JsonCpp 是一个 C++ 用来处理 JSON 数据的开发包。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声明里面居然放的是结构体,不知道什么编译器支持这种语法。
基准测试程序
#include <iostream> #include <string> #include <sys/time.h> #include <time.h> #include <json/json.h> usingnamespacestd; int64_t getCurrentTime() { structtimeval tval; gettimeofday(&tval, NULL); return(tval.tv_sec * 1000000LL + tval.tv_usec); } char* str ="abcdefghijklmnopqrstuvwxyz"; voidtest1() { intdoc_count = 40; intouter_field_count = 80; Json::Value common_info; int64_t start_time = getCurrentTime(); for(size_ti=0; i<doc_count; ++i) { Json::Value auc_info; for(size_tj=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; } voidtest2() { intdoc_count = 40; intouter_field_count = 80; Json::Value common_info; int64_t start_time = getCurrentTime(); Json::Value auc_info; for(size_ti=0; i<doc_count; ++i) { for(size_tj=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; } voidtest3() { intdoc_count = 40; intouter_field_count = 80; Json::Value common_info; int64_t start_time = getCurrentTime(); Json::Value auc_info; for(size_ti=0; i<doc_count; ++i) { for(size_tj=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; } intmain(intargc,constchar*argv[]) { test1(); test2(); test3(); return0; }
编译优化
默认情况下,JsonCpp编译时并没有带优化参数,自己可以加上优化参数。Linux环境下在下面这段代码中的CCFLAGS加入”O2″。
1 2 3 4 </td> | elifplatform.startswith('linux-gcc'): env.Tool('default') env.Append( LIBS=['pthread'], CCFLAGS="-Wall -fPIC O2") env['SHARED_LIB_ENABLED']=True | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 </td> | append time: 4946 opt append time: 3326 StaticString time: 2750 append time: 1825 opt append time: 1082 StaticString time: 845 | </tr> </tbody> </table> </div> </div>
1 2 3 4 5 6 7 </td> | void Value::setValue(constStaticString& value ) { type_ = stringValue; allocated_ =false; value_.string_ =const_cast<char*>( value.c_str() ); } | </tr> </tbody> </table> </div> </div>
1 2 3 4 </td> | append time: 1849 opt append time: 1067 StaticString time: 843 setValue time: 570 | </tr> </tbody> </table> </div> </div>
1 2 3 4 | append time: 1682 opt append time: 1011 StaticString time: 801 setValue time: 541 |